glibc: cleanup long double support

- Add 128 bit long double support from current glibc and a few headers
  they need
- Move the existing 80 bit float support in a sub directory of generic,
  it is not universal to all archs (see file added in docs/develop/arch).
  Also include some new .h files for x86 that are needed after these
  changes (from newer versions of the glibc).
- Adjust Jamfiles for m68k, x86 and x86_64 to use the 80bit format
- Do not adjust arm jamfiles, it was wrongly using 80bit long double and
  should be fixed to use 64bit instead (which means the double functions
  can be used with aliases)
- Do not adjust powerpc jamfiles, because it uses yet another format and
  we build it without long double support anyways.

Note that I moved only the files that were creating compile errors,
quite likely more of the s_* and e_* files need to be moved to the
specific directories, see glibc list here:

https://sourceware.org/git/?p=glibc.git;a=tree;f=sysdeps/ieee754/ldbl-128
https://sourceware.org/git/?p=glibc.git;a=tree;f=sysdeps/ieee754/ldbl-96

Change-Id: Ic2d8a454ba9a3b99638e4fbb63daf02df0fea403
Reviewed-on: https://review.haiku-os.org/c/1143
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
PulkoMandy 2019-03-03 20:49:32 +01:00 committed by waddlesplash
parent 134abee09e
commit 4b2da9c371
57 changed files with 3782 additions and 136 deletions

View File

@ -0,0 +1,48 @@
Notes on long double support
============================
The "long double" type is different on each architecture. Depending on the
available hardware and ABI conventions, performance compromises, etc, there
may be many implementations of it. Here is a summary for our convenience.
128-bit IEEE
------------
Platforms: Sparc, ARM64, RISC-V
This is the standard long double type from IEEE754. It has 1 sign bit,
15 exponent bit, and 112 fractional part bits. It is the natural extension
of the 64bit double.
Sparc specifies this type in their ABI but no implementation actually has
the instructions, they instead trigger a trap which would software emulate
them. However, gcc short circuits this by default and calls C library
support functions directly.
64-bit IEEE
-----------
Platforms: ARM
This is the same representation as plain "double". ARM uses this for simplicity.
80-bit
------
Platform: x86, x86\_64, m68k
This intermediate format is used by x86 CPUs internally. It may end up being
faster than plain double there. It consists of a 64bit fractional part, 15
exponent bits, and 1 sign bit. This is convenient because the fractional part
is a relatively easy to handle 64bit number.
m68k uses a similar format, but padded to 96 bits (the extra 16 bits are unused).
double double
-------------
Platforms: PowerPC?
This is also a 128bit type, but the representation is just two 64bit doubles.
The value is the sum of the two halves. This format allows faster emulation
than a "true" 128bit long double, and the precision is almost as good.

View File

@ -13,8 +13,16 @@ for architectureObject in [ MultiArchSubDirSetup sparc ] {
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
MergeObject <$(architecture)>os_arch_$(TARGET_ARCH).o :
stack_frame.c
system_time.c
thread.c
time.c
tls.c
softfloat.c
fpu_add.c fpu_compare.c fpu_div.c fpu_explode.c fpu_implode.c
fpu_mul.c fpu_reg.S fpu_sqrt.c fpu_subr.c
generic_atomic.cpp
generic_system_time_nsecs.cpp
;

View File

@ -0,0 +1,141 @@
/*
* IBM Accurate Mathematical Library
* written by International Business Machines Corp.
* Copyright (C) 2001-2019 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*********************************************************************/
/* MODULE_NAME: uroot.c */
/* */
/* FUNCTION: usqrt */
/* */
/* FILES NEEDED: dla.h endian.h mydefs.h */
/* uroot.tbl */
/* */
/* An ultimate sqrt routine. Given an IEEE double machine number x */
/* it computes the correctly rounded (to nearest) value of square */
/* root of x. */
/* Assumption: Machine arithmetic operations are performed in */
/* round to nearest mode of IEEE 754 standard. */
/* */
/*********************************************************************/
#include "endian.h"
#include "mydefs.h"
#include <dla.h>
#include "MathLib.h"
#include "root.tbl"
#include <math-barriers.h>
#include <math_private.h>
#include <fenv_private.h>
/*********************************************************************/
/* An ultimate sqrt routine. Given an IEEE double machine number x */
/* it computes the correctly rounded (to nearest) value of square */
/* root of x. */
/*********************************************************************/
double
__ieee754_sqrt (double x)
{
static const double
rt0 = 9.99999999859990725855365213134618E-01,
rt1 = 4.99999999495955425917856814202739E-01,
rt2 = 3.75017500867345182581453026130850E-01,
rt3 = 3.12523626554518656309172508769531E-01;
static const double big = 134217728.0;
double y, t, del, res, res1, hy, z, zz, p, hx, tx, ty, s;
mynumber a, c = { { 0, 0 } };
int4 k;
a.x = x;
k = a.i[HIGH_HALF];
a.i[HIGH_HALF] = (k & 0x001fffff) | 0x3fe00000;
t = inroot[(k & 0x001fffff) >> 14];
s = a.x;
/*----------------- 2^-1022 <= | x |< 2^1024 -----------------*/
if (k > 0x000fffff && k < 0x7ff00000)
{
int rm = __fegetround ();
fenv_t env;
libc_feholdexcept_setround (&env, FE_TONEAREST);
double ret;
y = 1.0 - t * (t * s);
t = t * (rt0 + y * (rt1 + y * (rt2 + y * rt3)));
c.i[HIGH_HALF] = 0x20000000 + ((k & 0x7fe00000) >> 1);
y = t * s;
hy = (y + big) - big;
del = 0.5 * t * ((s - hy * hy) - (y - hy) * (y + hy));
res = y + del;
if (res == (res + 1.002 * ((y - res) + del)))
ret = res * c.x;
else
{
res1 = res + 1.5 * ((y - res) + del);
EMULV (res, res1, z, zz, p, hx, tx, hy, ty); /* (z+zz)=res*res1 */
res = ((((z - s) + zz) < 0) ? max (res, res1) :
min (res, res1));
ret = res * c.x;
}
math_force_eval (ret);
libc_fesetenv (&env);
double dret = x / ret;
if (dret != ret)
{
double force_inexact = 1.0 / 3.0;
math_force_eval (force_inexact);
/* The square root is inexact, ret is the round-to-nearest
value which may need adjusting for other rounding
modes. */
switch (rm)
{
#ifdef FE_UPWARD
case FE_UPWARD:
if (dret > ret)
ret = (res + 0x1p-1022) * c.x;
break;
#endif
#ifdef FE_DOWNWARD
case FE_DOWNWARD:
#endif
#ifdef FE_TOWARDZERO
case FE_TOWARDZERO:
#endif
#if defined FE_DOWNWARD || defined FE_TOWARDZERO
if (dret < ret)
ret = (res - 0x1p-1022) * c.x;
break;
#endif
default:
break;
}
}
/* Otherwise (x / ret == ret), either the square root was exact or
the division was inexact. */
return ret;
}
else
{
if ((k & 0x7ff00000) == 0x7ff00000)
return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
if (x == 0)
return x; /* sqrt(+0)=+0, sqrt(-0)=-0 */
if (k < 0)
return (x - x) / (x - x); /* sqrt(-ve)=sNaN */
return 0x1p-256 * __ieee754_sqrt (x * 0x1p512);
}
}
strong_alias (__ieee754_sqrt, __sqrt_finite)

View File

@ -0,0 +1,86 @@
/* e_sqrtf.c -- float version of e_sqrt.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@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.
* ====================================================
*/
#include <math.h>
#include <math_private.h>
static const float one = 1.0, tiny=1.0e-30;
float
__ieee754_sqrtf(float x)
{
float z;
int32_t sign = (int)0x80000000;
int32_t ix,s,q,m,t,i;
uint32_t r;
GET_FLOAT_WORD(ix,x);
/* take care of Inf and NaN */
if((ix&0x7f800000)==0x7f800000) {
return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if(ix<=0) {
if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */
else if(ix<0)
return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix>>23);
if(m==0) { /* subnormal x */
for(i=0;(ix&0x00800000)==0;i++) ix<<=1;
m -= i-1;
}
m -= 127; /* unbias exponent */
ix = (ix&0x007fffff)|0x00800000;
if(m&1) /* odd m, double x to make it even */
ix += ix;
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix += ix;
q = s = 0; /* q = sqrt(x) */
r = 0x01000000; /* r = moving bit from right to left */
while(r!=0) {
t = s+r;
if(t<=ix) {
s = t+r;
ix -= t;
q += r;
}
ix += ix;
r>>=1;
}
/* use floating add to find out rounding direction */
if(ix!=0) {
z = one-tiny; /* trigger inexact flag */
if (z>=one) {
z = one+tiny;
if (z>one)
q += 2;
else
q += (q&1);
}
}
ix = (q>>1)+0x3f000000;
ix += (m <<23);
SET_FLOAT_WORD(z,ix);
return z;
}
strong_alias (__ieee754_sqrtf, __sqrtf_finite)

View File

@ -1,66 +0,0 @@
/* Raise given exceptions.
Copyright (C) 1997,99,2000,01,02 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <fenv_libc.h>
#include <bp-sym.h>
#undef feraiseexcept
int
__feraiseexcept (int excepts)
{
fenv_union_t u;
/* Raise exceptions represented by EXCEPTS. It is the responsibility of
the OS to ensure that if multiple exceptions occur they are fed back
to this process in the proper way; this can happen in hardware,
anyway (in particular, inexact with overflow or underflow). */
/* Get the current state. */
u.fenv = fegetenv_register ();
/* Add the exceptions */
u.l[1] = (u.l[1]
| (excepts & FPSCR_STICKY_BITS)
/* Turn FE_INVALID into FE_INVALID_SOFTWARE. */
| (excepts >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT))
& FE_INVALID_SOFTWARE));
/* Store the new status word (along with the rest of the environment),
triggering any appropriate exceptions. */
fesetenv_register (u.fenv);
if ((excepts & FE_INVALID)
/* For some reason, some PowerPC chips (the 601, in particular)
don't have FE_INVALID_SOFTWARE implemented. Detect this
case and raise FE_INVALID_SNAN instead. */
&& !fetestexcept (FE_INVALID))
set_fpscr_bit (FPSCR_VXSNAN);
/* Success. */
return 0;
}
#include <shlib-compat.h>
#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
strong_alias (__feraiseexcept, __old_feraiseexcept)
compat_symbol (libm, BP_SYM (__old_feraiseexcept), BP_SYM (feraiseexcept), GLIBC_2_1);
#endif
libm_hidden_ver (__feraiseexcept, feraiseexcept)
versioned_symbol (libm, BP_SYM (__feraiseexcept), BP_SYM (feraiseexcept), GLIBC_2_2);

View File

@ -0,0 +1,122 @@
/* e_atan2l.c -- long double version of e_atan2.c.
* Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
*/
/*
* ====================================================
* 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.
* ====================================================
*/
/* __ieee754_atan2l(y,x)
* Method :
* 1. Reduce y to positive by atan2l(y,x)=-atan2l(-y,x).
* 2. Reduce x to positive by (if x and y are unexceptional):
* ARG (x+iy) = arctan(y/x) ... if x > 0,
* ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
*
* Special cases:
*
* ATAN2((anything), NaN ) is NaN;
* ATAN2(NAN , (anything) ) is NaN;
* ATAN2(+-0, +(anything but NaN)) is +-0 ;
* ATAN2(+-0, -(anything but NaN)) is +-pi ;
* ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
* ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
* ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
* ATAN2(+-INF,+INF ) is +-pi/4 ;
* ATAN2(+-INF,-INF ) is +-3pi/4;
* ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include <math.h>
#include <math_private.h>
static const _Float128
tiny = L(1.0e-4900),
zero = 0.0,
pi_o_4 = L(7.85398163397448309615660845819875699e-01), /* 3ffe921fb54442d18469898cc51701b8 */
pi_o_2 = L(1.57079632679489661923132169163975140e+00), /* 3fff921fb54442d18469898cc51701b8 */
pi = L(3.14159265358979323846264338327950280e+00), /* 4000921fb54442d18469898cc51701b8 */
pi_lo = L(8.67181013012378102479704402604335225e-35); /* 3f8dcd129024e088a67cc74020bbea64 */
_Float128
__ieee754_atan2l(_Float128 y, _Float128 x)
{
_Float128 z;
int64_t k,m,hx,hy,ix,iy;
uint64_t lx,ly;
GET_LDOUBLE_WORDS64(hx,lx,x);
ix = hx&0x7fffffffffffffffLL;
GET_LDOUBLE_WORDS64(hy,ly,y);
iy = hy&0x7fffffffffffffffLL;
if(((ix|((lx|-lx)>>63))>0x7fff000000000000LL)||
((iy|((ly|-ly)>>63))>0x7fff000000000000LL)) /* x or y is NaN */
return x+y;
if(((hx-0x3fff000000000000LL)|lx)==0) return __atanl(y); /* x=1.0L */
m = ((hy>>63)&1)|((hx>>62)&2); /* 2*sign(x)+sign(y) */
/* when y = 0 */
if((iy|ly)==0) {
switch(m) {
case 0:
case 1: return y; /* atan(+-0,+anything)=+-0 */
case 2: return pi+tiny;/* atan(+0,-anything) = pi */
case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
}
}
/* when x = 0 */
if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
/* when x is INF */
if(ix==0x7fff000000000000LL) {
if(iy==0x7fff000000000000LL) {
switch(m) {
case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
case 2: return 3*pi_o_4+tiny;/*atan(+INF,-INF)*/
case 3: return -3*pi_o_4-tiny;/*atan(-INF,-INF)*/
}
} else {
switch(m) {
case 0: return zero ; /* atan(+...,+INF) */
case 1: return -zero ; /* atan(-...,+INF) */
case 2: return pi+tiny ; /* atan(+...,-INF) */
case 3: return -pi-tiny ; /* atan(-...,-INF) */
}
}
}
/* when y is INF */
if(iy==0x7fff000000000000LL) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
/* compute y/x */
k = (iy-ix)>>48;
if(k > 120) z=pi_o_2+L(0.5)*pi_lo; /* |y/x| > 2**120 */
else if(hx<0&&k<-120) z=0; /* |y|/x < -2**120 */
else z=__atanl(fabsl(y/x)); /* safe to do y/x */
switch (m) {
case 0: return z ; /* atan(+,+) */
case 1: {
uint64_t zh;
GET_LDOUBLE_MSW64(zh,z);
SET_LDOUBLE_MSW64(z,zh ^ 0x8000000000000000ULL);
}
return z ; /* atan(-,+) */
case 2: return pi-(z-pi_lo);/* atan(+,-) */
default: /* case 3 */
return (z-pi_lo)-pi;/* atan(-,-) */
}
}
strong_alias (__ieee754_atan2l, __atan2l_finite)

View File

@ -0,0 +1,141 @@
/* e_hypotl.c -- long double version of e_hypot.c.
* Conversion to long double by Jakub Jelinek, jakub@redhat.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.
* ====================================================
*/
/* __ieee754_hypotl(x,y)
*
* Method :
* If (assume round-to-nearest) z=x*x+y*y
* has error less than sqrtl(2)/2 ulp, than
* sqrtl(z) has error less than 1 ulp (exercise).
*
* So, compute sqrtl(x*x+y*y) with some care as
* follows to get the error below 1 ulp:
*
* Assume x>y>0;
* (if possible, set rounding to round-to-nearest)
* 1. if x > 2y use
* x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
* where x1 = x with lower 64 bits cleared, x2 = x-x1; else
* 2. if x <= 2y use
* t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
* where t1 = 2x with lower 64 bits cleared, t2 = 2x-t1,
* y1= y with lower 64 bits chopped, y2 = y-y1.
*
* NOTE: scaling may be necessary if some argument is too
* large or too tiny
*
* Special cases:
* hypotl(x,y) is INF if x or y is +INF or -INF; else
* hypotl(x,y) is NAN if x or y is NAN.
*
* Accuracy:
* hypotl(x,y) returns sqrtl(x^2+y^2) with error less
* than 1 ulps (units in the last place)
*/
#include <math.h>
#include <math_private.h>
#include <math-underflow.h>
_Float128
__ieee754_hypotl(_Float128 x, _Float128 y)
{
_Float128 a,b,t1,t2,y1,y2,w;
int64_t j,k,ha,hb;
GET_LDOUBLE_MSW64(ha,x);
ha &= 0x7fffffffffffffffLL;
GET_LDOUBLE_MSW64(hb,y);
hb &= 0x7fffffffffffffffLL;
if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
SET_LDOUBLE_MSW64(a,ha); /* a <- |a| */
SET_LDOUBLE_MSW64(b,hb); /* b <- |b| */
if((ha-hb)>0x78000000000000LL) {return a+b;} /* x/y > 2**120 */
k=0;
if(ha > 0x5f3f000000000000LL) { /* a>2**8000 */
if(ha >= 0x7fff000000000000LL) { /* Inf or NaN */
uint64_t low;
w = a+b; /* for sNaN */
if (issignaling (a) || issignaling (b))
return w;
GET_LDOUBLE_LSW64(low,a);
if(((ha&0xffffffffffffLL)|low)==0) w = a;
GET_LDOUBLE_LSW64(low,b);
if(((hb^0x7fff000000000000LL)|low)==0) w = b;
return w;
}
/* scale a and b by 2**-9600 */
ha -= 0x2580000000000000LL;
hb -= 0x2580000000000000LL; k += 9600;
SET_LDOUBLE_MSW64(a,ha);
SET_LDOUBLE_MSW64(b,hb);
}
if(hb < 0x20bf000000000000LL) { /* b < 2**-8000 */
if(hb <= 0x0000ffffffffffffLL) { /* subnormal b or 0 */
uint64_t low;
GET_LDOUBLE_LSW64(low,b);
if((hb|low)==0) return a;
t1=0;
SET_LDOUBLE_MSW64(t1,0x7ffd000000000000LL); /* t1=2^16382 */
b *= t1;
a *= t1;
k -= 16382;
GET_LDOUBLE_MSW64 (ha, a);
GET_LDOUBLE_MSW64 (hb, b);
if (hb > ha)
{
t1 = a;
a = b;
b = t1;
j = ha;
ha = hb;
hb = j;
}
} else { /* scale a and b by 2^9600 */
ha += 0x2580000000000000LL; /* a *= 2^9600 */
hb += 0x2580000000000000LL; /* b *= 2^9600 */
k -= 9600;
SET_LDOUBLE_MSW64(a,ha);
SET_LDOUBLE_MSW64(b,hb);
}
}
/* medium size a and b */
w = a-b;
if (w>b) {
t1 = 0;
SET_LDOUBLE_MSW64(t1,ha);
t2 = a-t1;
w = sqrtl(t1*t1-(b*(-b)-t2*(a+t1)));
} else {
a = a+a;
y1 = 0;
SET_LDOUBLE_MSW64(y1,hb);
y2 = b - y1;
t1 = 0;
SET_LDOUBLE_MSW64(t1,ha+0x0001000000000000LL);
t2 = a - t1;
w = sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b)));
}
if(k!=0) {
uint64_t high;
t1 = 1;
GET_LDOUBLE_MSW64(high,t1);
SET_LDOUBLE_MSW64(t1,high+(k<<48));
w *= t1;
math_check_force_underflow_nonneg (w);
return w;
} else return w;
}
strong_alias (__ieee754_hypotl, __hypotl_finite)

View File

@ -0,0 +1,255 @@
/* s_atanl.c
*
* Inverse circular tangent for 128-bit long double precision
* (arctangent)
*
*
*
* SYNOPSIS:
*
* long double x, y, atanl();
*
* y = atanl( x );
*
*
*
* DESCRIPTION:
*
* Returns radian angle between -pi/2 and +pi/2 whose tangent is x.
*
* The function uses a rational approximation of the form
* t + t^3 P(t^2)/Q(t^2), optimized for |t| < 0.09375.
*
* The argument is reduced using the identity
* arctan x - arctan u = arctan ((x-u)/(1 + ux))
* and an 83-entry lookup table for arctan u, with u = 0, 1/8, ..., 10.25.
* Use of the table improves the execution speed of the routine.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE -19, 19 4e5 1.7e-34 5.4e-35
*
*
* WARNING:
*
* This program uses integer operations on bit fields of floating-point
* numbers. It does not work with data structures other than the
* structure assumed.
*
*/
/* Copyright 2001 by Stephen L. Moshier <moshier@na-net.ornl.gov>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see
<http://www.gnu.org/licenses/>. */
#include <float.h>
#include <math.h>
#include <math_private.h>
#include <math-underflow.h>
#include <libm-alias-ldouble.h>
/* arctan(k/8), k = 0, ..., 82 */
static const _Float128 atantbl[84] = {
L(0.0000000000000000000000000000000000000000E0),
L(1.2435499454676143503135484916387102557317E-1), /* arctan(0.125) */
L(2.4497866312686415417208248121127581091414E-1),
L(3.5877067027057222039592006392646049977698E-1),
L(4.6364760900080611621425623146121440202854E-1),
L(5.5859931534356243597150821640166127034645E-1),
L(6.4350110879328438680280922871732263804151E-1),
L(7.1882999962162450541701415152590465395142E-1),
L(7.8539816339744830961566084581987572104929E-1),
L(8.4415398611317100251784414827164750652594E-1),
L(8.9605538457134395617480071802993782702458E-1),
L(9.4200004037946366473793717053459358607166E-1),
L(9.8279372324732906798571061101466601449688E-1),
L(1.0191413442663497346383429170230636487744E0),
L(1.0516502125483736674598673120862998296302E0),
L(1.0808390005411683108871567292171998202703E0),
L(1.1071487177940905030170654601785370400700E0),
L(1.1309537439791604464709335155363278047493E0),
L(1.1525719972156675180401498626127513797495E0),
L(1.1722738811284763866005949441337046149712E0),
L(1.1902899496825317329277337748293183376012E0),
L(1.2068173702852525303955115800565576303133E0),
L(1.2220253232109896370417417439225704908830E0),
L(1.2360594894780819419094519711090786987027E0),
L(1.2490457723982544258299170772810901230778E0),
L(1.2610933822524404193139408812473357720101E0),
L(1.2722973952087173412961937498224804940684E0),
L(1.2827408797442707473628852511364955306249E0),
L(1.2924966677897852679030914214070816845853E0),
L(1.3016288340091961438047858503666855921414E0),
L(1.3101939350475556342564376891719053122733E0),
L(1.3182420510168370498593302023271362531155E0),
L(1.3258176636680324650592392104284756311844E0),
L(1.3329603993374458675538498697331558093700E0),
L(1.3397056595989995393283037525895557411039E0),
L(1.3460851583802539310489409282517796256512E0),
L(1.3521273809209546571891479413898128509842E0),
L(1.3578579772154994751124898859640585287459E0),
L(1.3633001003596939542892985278250991189943E0),
L(1.3684746984165928776366381936948529556191E0),
L(1.3734007669450158608612719264449611486510E0),
L(1.3780955681325110444536609641291551522494E0),
L(1.3825748214901258580599674177685685125566E0),
L(1.3868528702577214543289381097042486034883E0),
L(1.3909428270024183486427686943836432060856E0),
L(1.3948567013423687823948122092044222644895E0),
L(1.3986055122719575950126700816114282335732E0),
L(1.4021993871854670105330304794336492676944E0),
L(1.4056476493802697809521934019958079881002E0),
L(1.4089588955564736949699075250792569287156E0),
L(1.4121410646084952153676136718584891599630E0),
L(1.4152014988178669079462550975833894394929E0),
L(1.4181469983996314594038603039700989523716E0),
L(1.4209838702219992566633046424614466661176E0),
L(1.4237179714064941189018190466107297503086E0),
L(1.4263547484202526397918060597281265695725E0),
L(1.4288992721907326964184700745371983590908E0),
L(1.4313562697035588982240194668401779312122E0),
L(1.4337301524847089866404719096698873648610E0),
L(1.4360250423171655234964275337155008780675E0),
L(1.4382447944982225979614042479354815855386E0),
L(1.4403930189057632173997301031392126865694E0),
L(1.4424730991091018200252920599377292525125E0),
L(1.4444882097316563655148453598508037025938E0),
L(1.4464413322481351841999668424758804165254E0),
L(1.4483352693775551917970437843145232637695E0),
L(1.4501726582147939000905940595923466567576E0),
L(1.4519559822271314199339700039142990228105E0),
L(1.4536875822280323362423034480994649820285E0),
L(1.4553696664279718992423082296859928222270E0),
L(1.4570043196511885530074841089245667532358E0),
L(1.4585935117976422128825857356750737658039E0),
L(1.4601391056210009726721818194296893361233E0),
L(1.4616428638860188872060496086383008594310E0),
L(1.4631064559620759326975975316301202111560E0),
L(1.4645314639038178118428450961503371619177E0),
L(1.4659193880646627234129855241049975398470E0),
L(1.4672716522843522691530527207287398276197E0),
L(1.4685896086876430842559640450619880951144E0),
L(1.4698745421276027686510391411132998919794E0),
L(1.4711276743037345918528755717617308518553E0),
L(1.4723501675822635384916444186631899205983E0),
L(1.4735431285433308455179928682541563973416E0), /* arctan(10.25) */
L(1.5707963267948966192313216916397514420986E0) /* pi/2 */
};
/* arctan t = t + t^3 p(t^2) / q(t^2)
|t| <= 0.09375
peak relative error 5.3e-37 */
static const _Float128
p0 = L(-4.283708356338736809269381409828726405572E1),
p1 = L(-8.636132499244548540964557273544599863825E1),
p2 = L(-5.713554848244551350855604111031839613216E1),
p3 = L(-1.371405711877433266573835355036413750118E1),
p4 = L(-8.638214309119210906997318946650189640184E-1),
q0 = L(1.285112506901621042780814422948906537959E2),
q1 = L(3.361907253914337187957855834229672347089E2),
q2 = L(3.180448303864130128268191635189365331680E2),
q3 = L(1.307244136980865800160844625025280344686E2),
q4 = L(2.173623741810414221251136181221172551416E1);
/* q5 = 1.000000000000000000000000000000000000000E0 */
static const _Float128 huge = L(1.0e4930);
_Float128
__atanl (_Float128 x)
{
int k, sign;
_Float128 t, u, p, q;
ieee854_long_double_shape_type s;
s.value = x;
k = s.parts32.w0;
if (k & 0x80000000)
sign = 1;
else
sign = 0;
/* Check for IEEE special cases. */
k &= 0x7fffffff;
if (k >= 0x7fff0000)
{
/* NaN. */
if ((k & 0xffff) | s.parts32.w1 | s.parts32.w2 | s.parts32.w3)
return (x + x);
/* Infinity. */
if (sign)
return -atantbl[83];
else
return atantbl[83];
}
if (k <= 0x3fc50000) /* |x| < 2**-58 */
{
math_check_force_underflow (x);
/* Raise inexact. */
if (huge + x > 0.0)
return x;
}
if (k >= 0x40720000) /* |x| > 2**115 */
{
/* Saturate result to {-,+}pi/2 */
if (sign)
return -atantbl[83];
else
return atantbl[83];
}
if (sign)
x = -x;
if (k >= 0x40024800) /* 10.25 */
{
k = 83;
t = -1.0/x;
}
else
{
/* Index of nearest table element.
Roundoff to integer is asymmetrical to avoid cancellation when t < 0
(cf. fdlibm). */
k = 8.0 * x + 0.25;
u = L(0.125) * k;
/* Small arctan argument. */
t = (x - u) / (1.0 + x * u);
}
/* Arctan of small argument t. */
u = t * t;
p = ((((p4 * u) + p3) * u + p2) * u + p1) * u + p0;
q = ((((u + q4) * u + q3) * u + q2) * u + q1) * u + q0;
u = t * u * p / q + t;
/* arctan x = arctan u + arctan t */
u = atantbl[k] + u;
if (sign)
return (-u);
else
return u;
}
libm_alias_ldouble (__atan, atan)

View File

@ -0,0 +1,40 @@
/* s_copysignl.c -- long double version of s_copysign.c.
* Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
*/
/*
* ====================================================
* 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
/*
* copysignl(long double x, long double y)
* copysignl(x,y) returns a value with the magnitude of x and
* with the sign bit of y.
*/
#define NO_MATH_REDIRECT
#include <math.h>
#include <math_private.h>
#include <libm-alias-ldouble.h>
_Float128 __copysignl(_Float128 x, _Float128 y)
{
uint64_t hx,hy;
GET_LDOUBLE_MSW64(hx,x);
GET_LDOUBLE_MSW64(hy,y);
SET_LDOUBLE_MSW64(x,(hx&0x7fffffffffffffffULL)
|(hy&0x8000000000000000ULL));
return x;
}
libm_alias_ldouble (__copysign, copysign)

View File

@ -0,0 +1,44 @@
/* Return classification value corresponding to argument.
Copyright (C) 1997-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
Jakub Jelinek <jj@ultra.linux.cz>, 1999.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <math.h>
#include <math_private.h>
int
__fpclassifyl (_Float128 x)
{
uint64_t hx, lx;
int retval = FP_NORMAL;
GET_LDOUBLE_WORDS64 (hx, lx, x);
lx |= (hx & 0x0000ffffffffffffLL);
hx &= 0x7fff000000000000LL;
if ((hx | lx) == 0)
retval = FP_ZERO;
else if (hx == 0)
retval = FP_SUBNORMAL;
else if (hx == 0x7fff000000000000LL)
retval = lx != 0 ? FP_NAN : FP_INFINITE;
return retval;
}
libm_hidden_def (__fpclassifyl)

View File

@ -0,0 +1,29 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Change for long double by Jakub Jelinek <jj@ultra.linux.cz>
* Public domain.
*/
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: $";
#endif
/*
* isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0;
* no branching!
*/
#include <math.h>
#include <math_private.h>
int
__isinfl (_Float128 x)
{
int64_t hx,lx;
GET_LDOUBLE_WORDS64(hx,lx,x);
lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7fff000000000000LL;
lx |= -lx;
return ~(lx >> 63) & (hx >> 62);
}
//mathx_hidden_def (__isinfl)
//weak_alias (__isinfl, isinfl)

View File

@ -0,0 +1,38 @@
/* s_isnanl.c -- long double version of s_isnan.c.
* Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
*/
/*
* ====================================================
* 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
/*
* isnanl(x) returns 1 is x is nan, else 0;
* no branching!
*/
#include <math.h>
#include <math_private.h>
int __isnanl(_Float128 x)
{
int64_t hx,lx;
GET_LDOUBLE_WORDS64(hx,lx,x);
hx &= 0x7fffffffffffffffLL;
hx |= (uint64_t)(lx|(-lx))>>63;
hx = 0x7fff000000000000LL - hx;
return (int)((uint64_t)hx>>63);
}
//mathx_hidden_def (__isnanl)
//weak_alias (__isnanl, isnanl)

View File

@ -0,0 +1,46 @@
/* Test for signaling NaN.
Copyright (C) 2013-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <math.h>
#include <math_private.h>
#include <nan-high-order-bit.h>
int
__issignalingl (_Float128 x)
{
uint64_t hxi, lxi __attribute__ ((unused));
GET_LDOUBLE_WORDS64 (hxi, lxi, x);
#if HIGH_ORDER_BIT_IS_SET_FOR_SNAN
/* We only have to care about the high-order bit of x's significand, because
having it set (sNaN) already makes the significand different from that
used to designate infinity. */
return ((hxi & UINT64_C (0x7fff800000000000))
== UINT64_C (0x7fff800000000000));
#else
/* To keep the following comparison simple, toggle the quiet/signaling bit,
so that it is set for sNaNs. This is inverse to IEEE 754-2008 (as well as
common practice for IEEE 754-1985). */
hxi ^= UINT64_C (0x0000800000000000);
/* If lxi != 0, then set any suitable bit of the significand in hxi. */
hxi |= (lxi | -lxi) >> 63;
/* We have to compare for greater (instead of greater or equal), because x's
significand being all-zero designates infinity not NaN. */
return (hxi & UINT64_C (0x7fffffffffffffff)) > UINT64_C (0x7fff800000000000);
#endif
}
libm_hidden_def (__issignalingl)

View File

@ -0,0 +1,27 @@
/* Return nonzero value if number is negative.
Copyright (C) 1997-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <math.h>
#include <math_private.h>
int
__signbitl (_Float128 x)
{
return __builtin_signbitl (x);
}

View File

@ -46,6 +46,7 @@ static char rcsid[] = "$NetBSD: $";
*/
#include "math.h"
#include "math_ldbl.h"
#include "math_private.h"
#ifdef __STDC__

View File

@ -172,6 +172,8 @@ for architectureObject in [ MultiArchSubDirSetup m68k ] {
SEARCH on [ FGristFiles $(genericSources) ]
= [ FDirName $(HAIKU_TOP) src system libroot posix glibc arch
generic ] ;
generic ]
[ FDirName $(HAIKU_TOP) src system libroot posix glibc arch
generic longdouble 80bit ] ;
}
}

View File

@ -19,8 +19,10 @@ SubDirCcFlags -D_GNU_SOURCE -D_IEEE_LIBM ;
local genericSources =
branred.c
cmp.c dbl2mpn.c divrem.c
doasin.c
dosincos.c
halfulp.c
ldbl2mpn.c
memrchr.c
mpa.c mpatan.c mpatan2.c mpexp.c mplog.c mpn2dbl.c
mpn2flt.c mpn2ldbl.c mpsqrt.c mptan.c
@ -29,34 +31,39 @@ local genericSources =
slowexp.c
slowpow.c
e_acosf.c
e_acosh.c e_acoshf.c # e_acoshl.c
e_atan2.c e_atan2f.c # e_atan2l.c
e_asin.c e_asinf.c
e_atan2.c e_atan2f.c e_atan2l.c
e_atanh.c e_atanhf.c # e_atanhl.c
e_cosh.c e_coshf.c # e_coshl.c
e_exp.c e_expf.c
e_fmod.c e_fmodf.c # e_fmodl.c
e_gamma_r.c e_gammaf_r.c
e_hypot.c e_hypotf.c # e_hypotl.c
e_hypot.c e_hypotf.c e_hypotl.c
e_j0.c e_j0f.c
e_j1.c e_j1f.c
e_jn.c e_jnf.c
e_lgamma_r.c e_lgammaf_r.c
e_log.c e_logf.c
e_log.c e_logf.c e_logl.c
e_log10.c e_log10f.c
e_pow.c e_powf.c # e_powl.c
e_rem_pio2f.c
e_remainder.c e_remainderf.c # e_remainderl.c
e_scalb.c e_scalbf.c # e_scalbl.c
e_sinh.c e_sinhf.c # e_sinhl.c
e_sqrt.c e_sqrtf.c
k_cos.c k_cosf.c
k_sin.c k_sinf.c
k_rem_pio2.c k_rem_pio2f.c # k_rem_pio2l.c
k_tan.c k_tanf.c
s_asinh.c s_asinhf.c # s_asinhl.c
s_atan.c s_atanf.c # s_atanl.c
s_atan.c s_atanf.c s_atanl.c
s_cbrt.c s_cbrtf.c # s_cbrtl.c
s_ceil.c s_ceilf.c # s_ceill.c
s_copysign.c s_copysignf.c # s_copysignl.c
s_clog.c s_clogf.c s_clogl.c
s_csqrt.c s_csqrtf.c s_csqrtl.c
s_copysign.c s_copysignf.c s_copysignl.c
s_cos.c s_cosf.c
s_erf.c s_erff.c # s_erfl.c
s_expm1f.c s_expm1.c
@ -66,23 +73,26 @@ local genericSources =
s_fma.c s_fmaf.c # s_fmal.c
s_fmax.c s_fmaxf.c # s_fmaxl.c
s_fmin.c s_fminf.c # s_fminl.c
s_fpclassify.c s_fpclassifyf.c # s_fpclassifyl.c
s_fpclassify.c s_fpclassifyf.c s_fpclassifyl.c
s_frexp.c s_frexpf.c # s_frexpl.c
s_ilogb.c s_ilogbf.c
s_isinf.c s_isinff.c # s_isinfl.c
s_isinf.c s_isinff.c s_isinfl.c
s_isnanl.c
s_issignalingl.c
s_ldexp.c s_ldexpf.c # s_ldexpl.c
s_llrint.c s_llrintf.c # s_llrintl.c
s_log1p.c s_log1pf.c
s_log1p.c s_log1pf.c s_log1pl.c
s_logb.c s_logbf.c # s_logbl.c
s_lrint.c s_lrintf.c # s_lrintl.c
s_lround.c s_lroundf.c
s_modf.c s_modff.c # s_modfl.c
s_nan.c s_nanf.c # s_nanl.c
s_nan.c s_nanf.c s_nanl.c
s_nextafter.c s_nextafterf.c # s_nextafterl.c
s_nexttoward.c # s_nexttowardf.c s_nexttowardl.c
s_rint.c s_rintf.c
s_round.c s_roundf.c # s_roundl.c
s_scalbn.c s_scalbnf.c # s_scalbnl.c
s_signbit.c s_signbitf.c # s_signbitl.c
s_signbit.c s_signbitf.c s_signbitl.c
s_significand.c s_significandf.c
s_signgam.c
s_sin.c s_sinf.c # s_sinl.c
@ -93,14 +103,14 @@ local genericSources =
t_exp.c
w_acos.c w_acosf.c # w_acosl.c
w_acosh.c w_acoshf.c # w_acoshl.c
w_atan2.c w_atan2f.c # w_atan2l.c
w_atan2.c w_atan2f.c w_atan2l.c
w_asin.c w_asinf.c # w_asinl.c
w_atanh.c w_atanhf.c # w_atanhl.c
w_cosh.c w_coshf.c # w_coshl.c
w_drem.c w_dremf.c # w_dreml.c
w_exp.c w_expf.c # w_expl.c
w_fmod.c w_fmodf.c # w_fmodl.c
w_hypot.c w_hypotf.c # w_hypotl.c
w_hypot.c w_hypotf.c w_hypotl.c
w_j0.c w_j0f.c
w_j1.c w_j1f.c
w_jn.c w_jnf.c
@ -112,8 +122,8 @@ local genericSources =
w_remainder.c w_remainderf.c # w_remainderl.c
w_scalb.c w_scalbf.c # w_scalbl.c
w_sinh.c w_sinhf.c # w_sinhl.c
# no asm for m68k in glibc
w_sqrt.c w_sqrtf.c # w_sqrtl.c
w_sqrtl_compat.c
;
@ -122,18 +132,39 @@ MergeObject <$(TARGET_ARCH)>posix_gnu_arch_$(TARGET_ARCH)_generic.o :
;
#MergeObject <$(TARGET_ARCH)>posix_gnu_arch_$(TARGET_ARCH)_other.o :
# ;
MergeObject <$(TARGET_ARCH)>posix_gnu_arch_$(TARGET_ARCH)_e.o :
e_sqrtl.c
;
MergeObject <$(TARGET_ARCH)>posix_gnu_arch_$(TARGET_ARCH)_s.o :
s_isnan.S s_isnanf.S
;
MergeObject <$(TARGET_ARCH)>posix_gnu_arch_$(TARGET_ARCH)_other.o :
add_n.S
addmul_1.S
fegetround.c fesetround.c
feholdexcpt.c
fraiseexcpt.c
fesetenv.c
lshift.S rshift.S
mul_1.S
sub_n.S
submul_1.S
;
MergeObjectFromObjects <$(TARGET_ARCH)>posix_gnu_arch_$(TARGET_ARCH).o
: :
<$(TARGET_ARCH)>posix_gnu_arch_$(TARGET_ARCH)_e.o
<$(TARGET_ARCH)>posix_gnu_arch_$(TARGET_ARCH)_s.o
<$(TARGET_ARCH)>posix_gnu_arch_$(TARGET_ARCH)_generic.o
# <$(TARGET_ARCH)>posix_gnu_arch_$(TARGET_ARCH)_other.o
<$(TARGET_ARCH)>posix_gnu_arch_$(TARGET_ARCH)_other.o
;
SEARCH on [ FGristFiles $(genericSources) ]
= [ FDirName $(HAIKU_TOP) src system libroot posix glibc arch
generic ] ;
generic ]
[ FDirName $(HAIKU_TOP) src system libroot posix glibc arch
generic longdouble 128bit ] ;

View File

@ -0,0 +1,57 @@
/* SPARC v9 __mpn_add_n -- Add two limb vectors of the same length > 0 and
store sum in a third limb vector.
Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not,
see <http://www.gnu.org/licenses/>. */
#include <sysdep.h>
/* INPUT PARAMETERS
res_ptr %o0
s1_ptr %o1
s2_ptr %o2
size %o3 */
ENTRY(__mpn_add_n)
sub %g0,%o3,%g5
sllx %o3,3,%g1
add %o1,%g1,%o1 ! make s1_ptr point at end
add %o2,%g1,%o2 ! make s2_ptr point at end
add %o0,%g1,%o0 ! make res_ptr point at end
mov 0,%o4 ! clear carry variable
sllx %g5,3,%o5 ! compute initial address index
1: ldx [%o2+%o5],%g1 ! load s2 limb
add %g5,1,%g5 ! increment loop count
ldx [%o1+%o5],%o3 ! load s1 limb
addcc %g1,%o4,%g1 ! add s2 limb and carry variable
movcc %xcc,0,%o4 ! if carry-out, o4 was 1; clear it
addcc %g1,%o3,%g1 ! add s1 limb to sum
stx %g1,[%o0+%o5] ! store result
add %o5,8,%o5 ! increment address index
brnz,pt %g5,1b
movcs %xcc,1,%o4 ! if s1 add gave carry, record it
retl
mov %o4,%o0
END(__mpn_add_n)

View File

@ -0,0 +1,83 @@
/* SPARC v9 __mpn_addmul_1 -- Multiply a limb vector with a single limb and
add the product to a second limb vector.
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not,
see <http://www.gnu.org/licenses/>. */
#include <sysdep.h>
/* INPUT PARAMETERS
res_ptr o0
s1_ptr o1
size o2
s2_limb o3 */
ENTRY(__mpn_addmul_1)
save %sp,-192,%sp
sub %g0,%i2,%o7
mov 0,%o0 ! zero cy_limb
sllx %o7,3,%o7
sethi %hi(0x80000000),%o2
srl %i3,0,%o1 ! extract low 32 bits of s2_limb
sub %i1,%o7,%o3
srlx %i3,32,%i3 ! extract high 32 bits of s2_limb
sub %i0,%o7,%o4
add %o2,%o2,%o2 ! o2 = 0x100000000
! hi !
! mid-1 !
! mid-2 !
! lo !
1:
ldx [%o3+%o7],%g5
srl %g5,0,%i0 ! zero hi bits
ldx [%o4+%o7],%l1
srlx %g5,32,%g5
mulx %o1,%i0,%i4 ! lo product
mulx %i3,%i0,%i1 ! mid-1 product
mulx %o1,%g5,%l2 ! mid-2 product
mulx %i3,%g5,%i5 ! hi product
srlx %i4,32,%i0 ! extract high 32 bits of lo product...
add %i1,%i0,%i1 ! ...and add it to the mid-1 product
addcc %i1,%l2,%i1 ! add mid products
mov 0,%l0 ! we need the carry from that add...
movcs %xcc,%o2,%l0 ! ...compute it and...
sllx %i1,32,%i0 ! align low bits of mid product
add %i5,%l0,%i5 ! ...add to bit 32 of the hi product
srl %i4,0,%g5 ! zero high 32 bits of lo product
add %i0,%g5,%i0 ! combine into low 64 bits of result
srlx %i1,32,%i1 ! extract high bits of mid product...
addcc %i0,%o0,%i0 ! add cy_limb to low 64 bits of result
add %i5,%i1,%i1 ! ...and add them to the high result
mov 0,%g5
movcs %xcc,1,%g5
addcc %l1,%i0,%i0
stx %i0,[%o4+%o7]
add %g5,1,%l1
movcs %xcc,%l1,%g5
addcc %o7,8,%o7
bne,pt %xcc,1b
add %i1,%g5,%o0 ! compute new cy_limb
jmpl %i7+8, %g0
restore %o0,%g0,%o0
END(__mpn_addmul_1)

View File

@ -0,0 +1,31 @@
/* Long double square root, sparc64 version.
Copyright (C) 2000-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2000.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <math.h>
extern void _Qp_sqrt(long double *, const long double *);
long double
__ieee754_sqrtl (long double x)
{
long double ret;
_Qp_sqrt (&ret, &x);
return ret;
}
strong_alias (__ieee754_sqrtl, __sqrtl_finite)

View File

@ -0,0 +1,32 @@
/* Return current rounding direction.
Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <fenv.h>
int
__fegetround (void)
{
fenv_t tmp;
__fenv_stfsr (tmp);
return tmp & __FE_ROUND_MASK;
}
libm_hidden_def (__fegetround)
weak_alias (__fegetround, fegetround)
libm_hidden_weak (fegetround)

View File

@ -0,0 +1,14 @@
#include <fenv.h>
int
feholdexcept (fenv_t *e)
{
fenv_t etmp;
__fenv_stfsr(etmp);
*(e) = etmp;
etmp = etmp & ~((0x1f << 23) | FE_ALL_EXCEPT);
__fenv_ldfsr(etmp);
return 0;
}

View File

@ -0,0 +1,55 @@
/* Install given floating-point environment.
Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <shlib-compat.h>
int
__fesetenv (const fenv_t *envp)
{
fenv_t dummy;
/* Put these constants in memory explicitly, so as to cope with a
-fPIC bug as of gcc 970624. Making them automatic is quicker
than loading up the pic register in this instance. */
if (envp == FE_DFL_ENV)
{
dummy = 0;
envp = &dummy;
}
else if (envp == FE_NOMASK_ENV)
{
dummy = 0x1f << 23;
envp = &dummy;
}
__fenv_ldfsr (*envp);
/* Success. */
return 0;
}
#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
strong_alias (__fesetenv, __old_fesetenv)
compat_symbol (libm, __old_fesetenv, fesetenv, GLIBC_2_1);
#endif
libm_hidden_def (__fesetenv)
libm_hidden_ver (__fesetenv, fesetenv)
versioned_symbol (libm, __fesetenv, fesetenv, GLIBC_2_2);

View File

@ -0,0 +1,39 @@
/* Set current rounding direction.
Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <fenv.h>
int
__fesetround (int round)
{
fenv_t tmp;
if ((round & ~__FE_ROUND_MASK) != 0)
/* ROUND is no valid rounding mode. */
return 1;
__fenv_stfsr (tmp);
tmp &= ~__FE_ROUND_MASK;
tmp |= round;
__fenv_ldfsr (tmp);
return 0;
}
libm_hidden_def (__fesetround)
weak_alias (__fesetround, fesetround)
libm_hidden_weak (fesetround)

View File

@ -0,0 +1,91 @@
/* Raise given exceptions.
Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <float.h>
#include <math.h>
#include <shlib-compat.h>
int
__feraiseexcept (int excepts)
{
static const struct {
double zero, one, max, min, pi;
} c = {
0.0, 1.0, DBL_MAX, DBL_MIN, M_PI
};
double d;
/* Raise exceptions represented by EXPECTS. But we must raise only
one signal at a time. It is important the if the overflow/underflow
exception and the inexact exception are given at the same time,
the overflow/underflow exception follows the inexact exception. */
/* First: invalid exception. */
if ((FE_INVALID & excepts) != 0)
{
/* One example of an invalid operation is 0/0. */
__asm ("" : "=e" (d) : "0" (c.zero));
d /= c.zero;
__asm __volatile ("" : : "e" (d));
}
/* Next: division by zero. */
if ((FE_DIVBYZERO & excepts) != 0)
{
__asm ("" : "=e" (d) : "0" (c.one));
d /= c.zero;
__asm __volatile ("" : : "e" (d));
}
/* Next: overflow. */
if ((FE_OVERFLOW & excepts) != 0)
{
__asm ("" : "=e" (d) : "0" (c.max));
d *= d;
__asm __volatile ("" : : "e" (d));
}
/* Next: underflow. */
if ((FE_UNDERFLOW & excepts) != 0)
{
__asm ("" : "=e" (d) : "0" (c.min));
d *= d;
__asm __volatile ("" : : "e" (d));
}
/* Last: inexact. */
if ((FE_INEXACT & excepts) != 0)
{
__asm ("" : "=e" (d) : "0" (c.one));
d /= c.pi;
__asm __volatile ("" : : "e" (d));
}
/* Success. */
return 0;
}
#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
strong_alias (__feraiseexcept, __old_feraiseexcept)
compat_symbol (libm, __old_feraiseexcept, feraiseexcept, GLIBC_2_1);
#endif
libm_hidden_def (__feraiseexcept)
libm_hidden_ver (__feraiseexcept, feraiseexcept)
versioned_symbol (libm, __feraiseexcept, feraiseexcept, GLIBC_2_2);

View File

@ -0,0 +1,95 @@
/* SPARC v9 __mpn_lshift --
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not,
see <http://www.gnu.org/licenses/>. */
#include "sysdep.h"
/* INPUT PARAMETERS
res_ptr %o0
src_ptr %o1
size %o2
cnt %o3 */
.register %g2, #scratch
.register %g3, #scratch
ENTRY(__mpn_lshift)
sllx %o2,3,%g1
add %o1,%g1,%o1 ! make %o1 point at end of src
ldx [%o1-8],%g2 ! load first limb
sub %g0,%o3,%o5 ! negate shift count
add %o0,%g1,%o0 ! make %o0 point at end of res
add %o2,-1,%o2
andcc %o2,4-1,%g4 ! number of limbs in first loop
srlx %g2,%o5,%g1 ! compute function result
be,pn %xcc,.L0 ! if multiple of 4 limbs, skip first loop
mov %g1,%g5
sub %o2,%g4,%o2 ! adjust count for main loop
.Loop0: ldx [%o1-16],%g3
add %o0,-8,%o0
add %o1,-8,%o1
sllx %g2,%o3,%o4
addcc %g4,-1,%g4
srlx %g3,%o5,%g1
mov %g3,%g2
or %o4,%g1,%o4
bne,pt %xcc,.Loop0
stx %o4,[%o0+0]
.L0: brz,pn %o2,.Lend
nop
.Loop: ldx [%o1-16],%g3
add %o0,-32,%o0
sllx %g2,%o3,%o4
addcc %o2,-4,%o2
srlx %g3,%o5,%g1
ldx [%o1-24],%g2
sllx %g3,%o3,%g4
or %o4,%g1,%o4
stx %o4,[%o0+24]
srlx %g2,%o5,%g1
ldx [%o1-32],%g3
sllx %g2,%o3,%o4
or %g4,%g1,%g4
stx %g4,[%o0+16]
srlx %g3,%o5,%g1
ldx [%o1-40],%g2
sllx %g3,%o3,%g4
or %o4,%g1,%o4
stx %o4,[%o0+8]
srlx %g2,%o5,%g1
add %o1,-32,%o1
or %g4,%g1,%g4
bne,pt %xcc,.Loop
stx %g4,[%o0+0]
.Lend: sllx %g2,%o3,%g2
stx %g2,[%o0-8]
jmpl %o7+8, %g0
mov %g5,%o0
END(__mpn_lshift)

View File

@ -0,0 +1,82 @@
/* SPARC v9 __mpn_mul_1 -- Multiply a limb vector with a single limb and
store the product in a second limb vector.
Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not,
see <http://www.gnu.org/licenses/>. */
#include <sysdep.h>
/* INPUT PARAMETERS
res_ptr o0
s1_ptr o1
size o2
s2_limb o3 */
ENTRY(__mpn_mul_1)
!#PROLOGUE# 0
save %sp,-192,%sp
!#PROLOGUE# 1
sub %g0,%i2,%o7
sllx %o7,3,%g5
sub %i1,%g5,%o3
sub %i0,%g5,%o4
mov 0,%o0 ! zero cy_limb
srl %i3,0,%o1 ! extract low 32 bits of s2_limb
srlx %i3,32,%i3 ! extract high 32 bits of s2_limb
mov 1,%o2
sllx %o2,32,%o2 ! o2 = 0x100000000
! hi !
! mid-1 !
! mid-2 !
! lo !
.Loop:
sllx %o7,3,%g1
ldx [%o3+%g1],%g5
srl %g5,0,%i0 ! zero hi bits
srlx %g5,32,%g5
mulx %o1,%i0,%i4 ! lo product
mulx %i3,%i0,%i1 ! mid-1 product
mulx %o1,%g5,%l2 ! mid-2 product
mulx %i3,%g5,%i5 ! hi product
srlx %i4,32,%i0 ! extract high 32 bits of lo product...
add %i1,%i0,%i1 ! ...and add it to the mid-1 product
addcc %i1,%l2,%i1 ! add mid products
mov 0,%l0 ! we need the carry from that add...
movcs %xcc,%o2,%l0 ! ...compute it and...
add %i5,%l0,%i5 ! ...add to bit 32 of the hi product
sllx %i1,32,%i0 ! align low bits of mid product
srl %i4,0,%g5 ! zero high 32 bits of lo product
add %i0,%g5,%i0 ! combine into low 64 bits of result
srlx %i1,32,%i1 ! extract high bits of mid product...
add %i5,%i1,%i1 ! ...and add them to the high result
addcc %i0,%o0,%i0 ! add cy_limb to low 64 bits of result
mov 0,%g5
movcs %xcc,1,%g5
addcc %o7,1,%o7
stx %i0,[%o4+%g1]
bne,pt %xcc,.Loop
add %i1,%g5,%o0 ! compute new cy_limb
jmpl %i7+8,%g0
restore %o0,%g0,%o0
END(__mpn_mul_1)

View File

@ -0,0 +1,92 @@
/* SPARC v9 __mpn_rshift --
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not,
see <http://www.gnu.org/licenses/>. */
#include "sysdep.h"
/* INPUT PARAMETERS
res_ptr %o0
src_ptr %o1
size %o2
cnt %o3 */
.register %g2, #scratch
.register %g3, #scratch
ENTRY(__mpn_rshift)
ldx [%o1],%g2 ! load first limb
sub %g0,%o3,%o5 ! negate shift count
add %o2,-1,%o2
andcc %o2,4-1,%g4 ! number of limbs in first loop
sllx %g2,%o5,%g1 ! compute function result
be,pn %xcc,.L0 ! if multiple of 4 limbs, skip first loop
mov %g1,%g5
sub %o2,%g4,%o2 ! adjust count for main loop
.Loop0: ldx [%o1+8],%g3
add %o0,8,%o0
add %o1,8,%o1
srlx %g2,%o3,%o4
addcc %g4,-1,%g4
sllx %g3,%o5,%g1
mov %g3,%g2
or %o4,%g1,%o4
bne,pt %xcc,.Loop0
stx %o4,[%o0-8]
.L0: brz,pn %o2,.Lend
nop
.Loop: ldx [%o1+8],%g3
add %o0,32,%o0
srlx %g2,%o3,%o4
addcc %o2,-4,%o2
sllx %g3,%o5,%g1
ldx [%o1+16],%g2
srlx %g3,%o3,%g4
or %o4,%g1,%o4
stx %o4,[%o0-32]
sllx %g2,%o5,%g1
ldx [%o1+24],%g3
srlx %g2,%o3,%o4
or %g4,%g1,%g4
stx %g4,[%o0-24]
sllx %g3,%o5,%g1
ldx [%o1+32],%g2
srlx %g3,%o3,%g4
or %o4,%g1,%o4
stx %o4,[%o0-16]
sllx %g2,%o5,%g1
add %o1,32,%o1
or %g4,%g1,%g4
bne,pt %xcc,.Loop
stx %g4,[%o0-8]
.Lend: srlx %g2,%o3,%g2
stx %g2,[%o0-0]
jmpl %o7+8,%g0
mov %g5,%o0
END(__mpn_rshift)

View File

@ -0,0 +1,33 @@
/* isnan(). sparc64 version.
Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <sysdep.h>
ENTRY (__isnan)
std %f0, [%sp + STACK_BIAS + 128]
sethi %hi(0x7ff00000), %g1
ldx [%sp + STACK_BIAS + 128], %o0
sllx %g1, 32, %g1
sllx %o0, 1, %o0
srlx %o0, 1, %o0
sub %g1, %o0, %o0
retl
srlx %o0, 63, %o0
END (__isnan)
hidden_def (__isnan)
weak_alias (__isnan, isnan)

View File

@ -0,0 +1,32 @@
/* isnanf(). sparc64 version.
Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <sysdep.h>
ENTRY (__isnanf)
st %f1, [%sp + STACK_BIAS + 128]
sethi %hi(0x7f800000), %g1
lduw [%sp + STACK_BIAS + 128], %o0
sll %o0, 1, %o0
srl %o0, 1, %o0
sub %g1, %o0, %o0
retl
srl %o0, 31, %o0
END (__isnanf)
hidden_def (__isnanf)
weak_alias (__isnanf, isnanf)

View File

@ -0,0 +1,54 @@
/* SPARC v9 __mpn_sub_n -- Subtract two limb vectors of the same length > 0
and store difference in a third limb vector.
Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not,
see <http://www.gnu.org/licenses/>. */
#include <sysdep.h>
/* INPUT PARAMETERS
res_ptr %o0
s1_ptr %o1
s2_ptr %o2
size %o3 */
ENTRY(__mpn_sub_n)
sub %g0,%o3,%g5
sllx %o3,3,%g1
add %o1,%g1,%o1 ! make s1_ptr point at end
add %o2,%g1,%o2 ! make s2_ptr point at end
add %o0,%g1,%o0 ! make res_ptr point at end
mov 0,%o4 ! clear carry variable
sllx %g5,3,%o5 ! compute initial address index
1: ldx [%o2+%o5],%g1 ! load s2 limb
add %g5,1,%g5 ! increment loop count
ldx [%o1+%o5],%o3 ! load s1 limb
addcc %g1,%o4,%g1 ! add s2 limb and carry variable
movcc %xcc,0,%o4 ! if carry-out, o4 was 1; clear it
subcc %o3,%g1,%g1 ! subtract s1 limb from sum
stx %g1,[%o0+%o5] ! store result
add %o5,8,%o5 ! increment address index
brnz,pt %g5,1b
movcs %xcc,1,%o4 ! if s1 subtract gave carry, record it
retl
mov %o4,%o0
END(__mpn_sub_n)

View File

@ -0,0 +1,82 @@
/* SPARC v9 __mpn_submul_1 -- Multiply a limb vector with a single limb and
subtract the product from a second limb vector.
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not,
see <http://www.gnu.org/licenses/>. */
#include <sysdep.h>
/* INPUT PARAMETERS
res_ptr o0
s1_ptr o1
size o2
s2_limb o3 */
ENTRY(__mpn_submul_1)
save %sp,-192,%sp
sub %g0,%i2,%o7
mov 0,%o0 ! zero cy_limb
sllx %o7,3,%o7
sethi %hi(0x80000000),%o2
srl %i3,0,%o1 ! extract low 32 bits of s2_limb
sub %i1,%o7,%o3
srlx %i3,32,%i3 ! extract high 32 bits of s2_limb
sub %i0,%o7,%o4
add %o2,%o2,%o2 ! o2 = 0x100000000
! hi !
! mid-1 !
! mid-2 !
! lo !
1:
ldx [%o3+%o7],%g5
srl %g5,0,%i0 ! zero hi bits
ldx [%o4+%o7],%l1
srlx %g5,32,%g5
mulx %o1,%i0,%i4 ! lo product
mulx %i3,%i0,%i1 ! mid-1 product
mulx %o1,%g5,%l2 ! mid-2 product
mulx %i3,%g5,%i5 ! hi product
srlx %i4,32,%i0 ! extract high 32 bits of lo product...
add %i1,%i0,%i1 ! ...and add it to the mid-1 product
addcc %i1,%l2,%i1 ! add mid products
mov 0,%l0 ! we need the carry from that add...
movcs %xcc,%o2,%l0 ! ...compute it and...
sllx %i1,32,%i0 ! align low bits of mid product
add %i5,%l0,%i5 ! ...add to bit 32 of the hi product
srl %i4,0,%g5 ! zero high 32 bits of lo product
add %i0,%g5,%i0 ! combine into low 64 bits of result
srlx %i1,32,%i1 ! extract high bits of mid product...
addcc %i0,%o0,%i0 ! add cy_limb to low 64 bits of result
add %i5,%i1,%i1 ! ...and add them to the high result
mov 0,%g5
movcs %xcc,1,%g5
subcc %l1,%i0,%i0
stx %i0,[%o4+%o7]
add %g5,1,%l1
movcs %xcc,%l1,%g5
addcc %o7,8,%o7
bne,pt %xcc,1b
add %i1,%g5,%o0 ! compute new cy_limb
jmpl %i7+8, %g0
restore %o0,%g0,%o0
END(__mpn_submul_1)

View File

@ -197,6 +197,8 @@ for architectureObject in [ MultiArchSubDirSetup x86 x86_gcc2 ] {
SEARCH on [ FGristFiles $(genericSources) ]
= [ FDirName $(HAIKU_TOP) src system libroot posix glibc arch
generic ] ;
generic ]
[ FDirName $(HAIKU_TOP) src system libroot posix glibc arch
generic longdouble 80bit ] ;
}
}

View File

@ -140,6 +140,8 @@ for architectureObject in [ MultiArchSubDirSetup x86_64 ] {
SEARCH on [ FGristFiles $(genericSources) ]
= [ FDirName $(HAIKU_TOP) src system libroot posix glibc arch
generic ] ;
generic ]
[ FDirName $(HAIKU_TOP) src system libroot posix glibc arch
generic longdouble 80bit ] ;
}
}

View File

@ -0,0 +1,329 @@
/* Macros to control TS 18661-3 glibc features where the same
definitions are appropriate for all platforms.
Copyright (C) 2017-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _BITS_FLOATN_COMMON_H
#define _BITS_FLOATN_COMMON_H
#include <features.h>
#include <bits/long-double.h>
/* This header should be included at the bottom of each bits/floatn.h.
It defines the following macros for each _FloatN and _FloatNx type,
where the same definitions, or definitions based only on the macros
in bits/floatn.h, are appropriate for all glibc configurations. */
/* Defined to 1 if the current compiler invocation provides a
floating-point type with the right format for this type, and this
glibc includes corresponding *fN or *fNx interfaces for it. */
#define __HAVE_FLOAT16 0
#define __HAVE_FLOAT32 1
#define __HAVE_FLOAT64 1
#define __HAVE_FLOAT32X 1
#define __HAVE_FLOAT128X 0
/* Defined to 1 if the corresponding __HAVE_<type> macro is 1 and the
type is the first with its format in the sequence of (the default
choices for) float, double, long double, _Float16, _Float32,
_Float64, _Float128, _Float32x, _Float64x, _Float128x for this
glibc; that is, if functions present once per floating-point format
rather than once per type are present for this type.
All configurations supported by glibc have _Float32 the same format
as float, _Float64 and _Float32x the same format as double, the
_Float64x the same format as either long double or _Float128. No
configurations support _Float128x or, as of GCC 7, have compiler
support for a type meeting the requirements for _Float128x. */
#define __HAVE_DISTINCT_FLOAT16 __HAVE_FLOAT16
#define __HAVE_DISTINCT_FLOAT32 0
#define __HAVE_DISTINCT_FLOAT64 0
#define __HAVE_DISTINCT_FLOAT32X 0
#define __HAVE_DISTINCT_FLOAT64X 0
#define __HAVE_DISTINCT_FLOAT128X __HAVE_FLOAT128X
/* Defined to 1 if the corresponding _FloatN type is not binary compatible
with the corresponding ISO C type in the current compilation unit as
opposed to __HAVE_DISTINCT_FLOATN, which indicates the default types built
in glibc. */
#define __HAVE_FLOAT128_UNLIKE_LDBL (__HAVE_DISTINCT_FLOAT128 \
&& __LDBL_MANT_DIG__ != 113)
/* Defined to 1 if any _FloatN or _FloatNx types that are not
ABI-distinct are however distinct types at the C language level (so
for the purposes of __builtin_types_compatible_p and _Generic). */
#if __GNUC_PREREQ (7, 0) && !defined __cplusplus
# define __HAVE_FLOATN_NOT_TYPEDEF 1
#else
# define __HAVE_FLOATN_NOT_TYPEDEF 0
#endif
#ifndef __ASSEMBLER__
/* Defined to concatenate the literal suffix to be used with _FloatN
or _FloatNx types, if __HAVE_<type> is 1. The corresponding
literal suffixes exist since GCC 7, for C only. */
# if __HAVE_FLOAT16
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
/* No corresponding suffix available for this type. */
# define __f16(x) ((_Float16) x##f)
# else
# define __f16(x) x##f16
# endif
# endif
# if __HAVE_FLOAT32
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# define __f32(x) x##f
# else
# define __f32(x) x##f32
# endif
# endif
# if __HAVE_FLOAT64
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# ifdef __NO_LONG_DOUBLE_MATH
# define __f64(x) x##l
# else
# define __f64(x) x
# endif
# else
# define __f64(x) x##f64
# endif
# endif
# if __HAVE_FLOAT32X
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# define __f32x(x) x
# else
# define __f32x(x) x##f32x
# endif
# endif
# if __HAVE_FLOAT64X
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# if __HAVE_FLOAT64X_LONG_DOUBLE
# define __f64x(x) x##l
# else
# define __f64x(x) __f128 (x)
# endif
# else
# define __f64x(x) x##f64x
# endif
# endif
# if __HAVE_FLOAT128X
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# error "_Float128X supported but no constant suffix"
# else
# define __f128x(x) x##f128x
# endif
# endif
/* Defined to a complex type if __HAVE_<type> is 1. */
# if __HAVE_FLOAT16
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef _Complex float __cfloat16 __attribute__ ((__mode__ (__HC__)));
# define __CFLOAT16 __cfloat16
# else
# define __CFLOAT16 _Complex _Float16
# endif
# endif
# if __HAVE_FLOAT32
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# define __CFLOAT32 _Complex float
# else
# define __CFLOAT32 _Complex _Float32
# endif
# endif
# if __HAVE_FLOAT64
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# ifdef __NO_LONG_DOUBLE_MATH
# define __CFLOAT64 _Complex long double
# else
# define __CFLOAT64 _Complex double
# endif
# else
# define __CFLOAT64 _Complex _Float64
# endif
# endif
# if __HAVE_FLOAT32X
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# define __CFLOAT32X _Complex double
# else
# define __CFLOAT32X _Complex _Float32x
# endif
# endif
# if __HAVE_FLOAT64X
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# if __HAVE_FLOAT64X_LONG_DOUBLE
# define __CFLOAT64X _Complex long double
# else
# define __CFLOAT64X __CFLOAT128
# endif
# else
# define __CFLOAT64X _Complex _Float64x
# endif
# endif
# if __HAVE_FLOAT128X
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# error "_Float128X supported but no complex type"
# else
# define __CFLOAT128X _Complex _Float128x
# endif
# endif
/* The remaining of this file provides support for older compilers. */
# if __HAVE_FLOAT16
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef float _Float16 __attribute__ ((__mode__ (__HF__)));
# endif
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf16() ((_Float16) __builtin_huge_val ())
# define __builtin_inff16() ((_Float16) __builtin_inf ())
# define __builtin_nanf16(x) ((_Float16) __builtin_nan (x))
# define __builtin_nansf16(x) ((_Float16) __builtin_nans (x))
# endif
# endif
# if __HAVE_FLOAT32
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef float _Float32;
# endif
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf32() (__builtin_huge_valf ())
# define __builtin_inff32() (__builtin_inff ())
# define __builtin_nanf32(x) (__builtin_nanf (x))
# define __builtin_nansf32(x) (__builtin_nansf (x))
# endif
# endif
# if __HAVE_FLOAT64
/* If double, long double and _Float64 all have the same set of
values, TS 18661-3 requires the usual arithmetic conversions on
long double and _Float64 to produce _Float64. For this to be the
case when building with a compiler without a distinct _Float64
type, _Float64 must be a typedef for long double, not for
double. */
# ifdef __NO_LONG_DOUBLE_MATH
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef long double _Float64;
# endif
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf64() (__builtin_huge_vall ())
# define __builtin_inff64() (__builtin_infl ())
# define __builtin_nanf64(x) (__builtin_nanl (x))
# define __builtin_nansf64(x) (__builtin_nansl (x))
# endif
# else
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef double _Float64;
# endif
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf64() (__builtin_huge_val ())
# define __builtin_inff64() (__builtin_inf ())
# define __builtin_nanf64(x) (__builtin_nan (x))
# define __builtin_nansf64(x) (__builtin_nans (x))
# endif
# endif
# endif
# if __HAVE_FLOAT32X
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef double _Float32x;
# endif
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf32x() (__builtin_huge_val ())
# define __builtin_inff32x() (__builtin_inf ())
# define __builtin_nanf32x(x) (__builtin_nan (x))
# define __builtin_nansf32x(x) (__builtin_nans (x))
# endif
# endif
# if __HAVE_FLOAT64X
# if __HAVE_FLOAT64X_LONG_DOUBLE
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef long double _Float64x;
# endif
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf64x() (__builtin_huge_vall ())
# define __builtin_inff64x() (__builtin_infl ())
# define __builtin_nanf64x(x) (__builtin_nanl (x))
# define __builtin_nansf64x(x) (__builtin_nansl (x))
# endif
# else
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef _Float128 _Float64x;
# endif
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf64x() (__builtin_huge_valf128 ())
# define __builtin_inff64x() (__builtin_inff128 ())
# define __builtin_nanf64x(x) (__builtin_nanf128 (x))
# define __builtin_nansf64x(x) (__builtin_nansf128 (x))
# endif
# endif
# endif
# if __HAVE_FLOAT128X
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# error "_Float128x supported but no type"
# endif
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf128x() ((_Float128x) __builtin_huge_val ())
# define __builtin_inff128x() ((_Float128x) __builtin_inf ())
# define __builtin_nanf128x(x) ((_Float128x) __builtin_nan (x))
# define __builtin_nansf128x(x) ((_Float128x) __builtin_nans (x))
# endif
# endif
#endif /* !__ASSEMBLER__. */
#endif /* _BITS_FLOATN_COMMON_H */

View File

@ -0,0 +1,183 @@
/*
* IBM Accurate Mathematical Library
* Written by International Business Machines Corp.
* Copyright (C) 2001-2019 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <math.h>
/***********************************************************************/
/*MODULE_NAME: dla.h */
/* */
/* This file holds C language macros for 'Double Length Floating Point */
/* Arithmetic'. The macros are based on the paper: */
/* T.J.Dekker, "A floating-point Technique for extending the */
/* Available Precision", Number. Math. 18, 224-242 (1971). */
/* A Double-Length number is defined by a pair (r,s), of IEEE double */
/* precision floating point numbers that satisfy, */
/* */
/* abs(s) <= abs(r+s)*2**(-53)/(1+2**(-53)). */
/* */
/* The computer arithmetic assumed is IEEE double precision in */
/* round to nearest mode. All variables in the macros must be of type */
/* IEEE double. */
/***********************************************************************/
/* CN = 1+2**27 = '41a0000002000000' IEEE double format. Use it to split a
double for better accuracy. */
#define CN 134217729.0
/* Exact addition of two single-length floating point numbers, Dekker. */
/* The macro produces a double-length number (z,zz) that satisfies */
/* z+zz = x+y exactly. */
#define EADD(x,y,z,zz) \
z=(x)+(y); zz=(fabs(x)>fabs(y)) ? (((x)-(z))+(y)) : (((y)-(z))+(x));
/* Exact subtraction of two single-length floating point numbers, Dekker. */
/* The macro produces a double-length number (z,zz) that satisfies */
/* z+zz = x-y exactly. */
#define ESUB(x,y,z,zz) \
z=(x)-(y); zz=(fabs(x)>fabs(y)) ? (((x)-(z))-(y)) : ((x)-((y)+(z)));
#ifdef __FP_FAST_FMA
# define DLA_FMS(x, y, z) __builtin_fma (x, y, -(z))
#endif
/* Exact multiplication of two single-length floating point numbers, */
/* Veltkamp. The macro produces a double-length number (z,zz) that */
/* satisfies z+zz = x*y exactly. p,hx,tx,hy,ty are temporary */
/* storage variables of type double. */
#ifdef DLA_FMS
# define EMULV(x, y, z, zz, p, hx, tx, hy, ty) \
z = x * y; zz = DLA_FMS (x, y, z);
#else
# define EMULV(x, y, z, zz, p, hx, tx, hy, ty) \
p = CN * (x); hx = ((x) - p) + p; tx = (x) - hx; \
p = CN * (y); hy = ((y) - p) + p; ty = (y) - hy; \
z = (x) * (y); zz = (((hx * hy - z) + hx * ty) + tx * hy) + tx * ty;
#endif
/* Exact multiplication of two single-length floating point numbers, Dekker. */
/* The macro produces a nearly double-length number (z,zz) (see Dekker) */
/* that satisfies z+zz = x*y exactly. p,hx,tx,hy,ty,q are temporary */
/* storage variables of type double. */
#ifdef DLA_FMS
# define MUL12(x,y,z,zz,p,hx,tx,hy,ty,q) \
EMULV(x,y,z,zz,p,hx,tx,hy,ty)
#else
# define MUL12(x,y,z,zz,p,hx,tx,hy,ty,q) \
p=CN*(x); hx=((x)-p)+p; tx=(x)-hx; \
p=CN*(y); hy=((y)-p)+p; ty=(y)-hy; \
p=hx*hy; q=hx*ty+tx*hy; z=p+q; zz=((p-z)+q)+tx*ty;
#endif
/* Double-length addition, Dekker. The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = x+xx + y+yy. */
/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. r,s are temporary */
/* storage variables of type double. */
#define ADD2(x, xx, y, yy, z, zz, r, s) \
r = (x) + (y); s = (fabs (x) > fabs (y)) ? \
(((((x) - r) + (y)) + (yy)) + (xx)) : \
(((((y) - r) + (x)) + (xx)) + (yy)); \
z = r + s; zz = (r - z) + s;
/* Double-length subtraction, Dekker. The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = x+xx - (y+yy). */
/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. r,s are temporary */
/* storage variables of type double. */
#define SUB2(x, xx, y, yy, z, zz, r, s) \
r = (x) - (y); s = (fabs (x) > fabs (y)) ? \
(((((x) - r) - (y)) - (yy)) + (xx)) : \
((((x) - ((y) + r)) + (xx)) - (yy)); \
z = r + s; zz = (r - z) + s;
/* Double-length multiplication, Dekker. The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = (x+xx)*(y+yy). */
/* An error bound: abs((x+xx)*(y+yy))*1.24e-31. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc are */
/* temporary storage variables of type double. */
#define MUL2(x, xx, y, yy, z, zz, p, hx, tx, hy, ty, q, c, cc) \
MUL12 (x, y, c, cc, p, hx, tx, hy, ty, q) \
cc = ((x) * (yy) + (xx) * (y)) + cc; z = c + cc; zz = (c - z) + cc;
/* Double-length division, Dekker. The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = (x+xx)/(y+yy). */
/* An error bound: abs((x+xx)/(y+yy))*1.50e-31. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc,u,uu */
/* are temporary storage variables of type double. */
#define DIV2(x,xx,y,yy,z,zz,p,hx,tx,hy,ty,q,c,cc,u,uu) \
c=(x)/(y); MUL12(c,y,u,uu,p,hx,tx,hy,ty,q) \
cc=(((((x)-u)-uu)+(xx))-c*(yy))/(y); z=c+cc; zz=(c-z)+cc;
/* Double-length addition, slower but more accurate than ADD2. */
/* The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = (x+xx)+(y+yy). */
/* An error bound: abs(x+xx + y+yy)*1.50e-31. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */
/* are temporary storage variables of type double. */
#define ADD2A(x, xx, y, yy, z, zz, r, rr, s, ss, u, uu, w) \
r = (x) + (y); \
if (fabs (x) > fabs (y)) { rr = ((x) - r) + (y); s = (rr + (yy)) + (xx); } \
else { rr = ((y) - r) + (x); s = (rr + (xx)) + (yy); } \
if (rr != 0.0) { \
z = r + s; zz = (r - z) + s; } \
else { \
ss = (fabs (xx) > fabs (yy)) ? (((xx) - s) + (yy)) : (((yy) - s) + (xx));\
u = r + s; \
uu = (fabs (r) > fabs (s)) ? ((r - u) + s) : ((s - u) + r); \
w = uu + ss; z = u + w; \
zz = (fabs (u) > fabs (w)) ? ((u - z) + w) : ((w - z) + u); }
/* Double-length subtraction, slower but more accurate than SUB2. */
/* The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = (x+xx)-(y+yy). */
/* An error bound: abs(x+xx - (y+yy))*1.50e-31. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */
/* are temporary storage variables of type double. */
#define SUB2A(x, xx, y, yy, z, zz, r, rr, s, ss, u, uu, w) \
r = (x) - (y); \
if (fabs (x) > fabs (y)) { rr = ((x) - r) - (y); s = (rr - (yy)) + (xx); } \
else { rr = (x) - ((y) + r); s = (rr + (xx)) - (yy); } \
if (rr != 0.0) { \
z = r + s; zz = (r - z) + s; } \
else { \
ss = (fabs (xx) > fabs (yy)) ? (((xx) - s) - (yy)) : ((xx) - ((yy) + s)); \
u = r + s; \
uu = (fabs (r) > fabs (s)) ? ((r - u) + s) : ((s - u) + r); \
w = uu + ss; z = u + w; \
zz = (fabs (u) > fabs (w)) ? ((u - z) + w) : ((w - z) + u); }

View File

@ -0,0 +1,65 @@
/* Define aliases for libm long double functions.
Copyright (C) 2017-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _LIBM_ALIAS_LDOUBLE_H
#define _LIBM_ALIAS_LDOUBLE_H
#include <bits/floatn.h>
#if __HAVE_FLOAT128 && !__HAVE_DISTINCT_FLOAT128
# define libm_alias_ldouble_other_r_f128(from, to, r) \
weak_alias (from ## l ## r, to ## f128 ## r)
#else
# define libm_alias_ldouble_other_r_f128(from, to, r)
#endif
#if __HAVE_FLOAT64X_LONG_DOUBLE
# define libm_alias_ldouble_other_r_f64x(from, to, r) \
weak_alias (from ## l ## r, to ## f64x ## r)
#else
# define libm_alias_ldouble_other_r_f64x(from, to, r)
#endif
/* Define _FloatN / _FloatNx aliases for a long double libm function
that has internal name FROM ## l ## R and public names TO ## suffix
## R for each suffix of a supported _FloatN / _FloatNx
floating-point type with the same format as long double. */
#define libm_alias_ldouble_other_r(from, to, r) \
libm_alias_ldouble_other_r_f128 (from, to, r); \
libm_alias_ldouble_other_r_f64x (from, to, r)
/* Likewise, but without the R suffix. */
#define libm_alias_ldouble_other(from, to) \
libm_alias_ldouble_other_r (from, to, )
/* Define aliases for a long double libm function that has internal
name FROM ## l ## R and public names TO ## suffix ## R for each
suffix of a supported floating-point type with the same format as
long double. This should only be used for functions where such
public names exist for _FloatN types, not for
implementation-namespace exported names (where there is one name
per format, not per type) or for obsolescent functions not provided
for _FloatN types. */
#define libm_alias_ldouble_r(from, to, r) \
weak_alias (from ## l ## r, to ## l ## r); \
libm_alias_ldouble_other_r (from, to, r)
/* Likewise, but without the R suffix. */
#define libm_alias_ldouble(from, to) libm_alias_ldouble_r (from, to, )
#endif

View File

@ -0,0 +1,27 @@
/* Specify NaN high-order bit conventions. Generic version.
Copyright (C) 2016-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef NAN_HIGH_ORDER_BIT_H
#define NAN_HIGH_ORDER_BIT_H 1
/* Define this macro to 1 if the high-order bit of a NaN's mantissa is
set for signaling NaNs and clear for quiet NaNs, 0 otherwise (the
preferred IEEE convention). */
#define HIGH_ORDER_BIT_IS_SET_FOR_SNAN 0
#endif /* nan-high-order-bit.h */

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997-2012 Free Software Foundation, Inc.
/* Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -19,70 +19,61 @@
# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
#endif
#include <bits/wordsize.h>
/* Define bits representing the exception. We use the bit positions
of the appropriate bits in the FPU control word. */
of the appropriate accrued exception bits from the FSR. */
enum
{
FE_INVALID = 0x01,
#define FE_INVALID FE_INVALID
__FE_DENORM = 0x02,
FE_DIVBYZERO = 0x04,
#define FE_DIVBYZERO FE_DIVBYZERO
FE_OVERFLOW = 0x08,
#define FE_OVERFLOW FE_OVERFLOW
FE_UNDERFLOW = 0x10,
#define FE_UNDERFLOW FE_UNDERFLOW
FE_INEXACT = 0x20
#define FE_INEXACT FE_INEXACT
FE_INVALID =
#define FE_INVALID (1 << 9)
FE_INVALID,
FE_OVERFLOW =
#define FE_OVERFLOW (1 << 8)
FE_OVERFLOW,
FE_UNDERFLOW =
#define FE_UNDERFLOW (1 << 7)
FE_UNDERFLOW,
FE_DIVBYZERO =
#define FE_DIVBYZERO (1 << 6)
FE_DIVBYZERO,
FE_INEXACT =
#define FE_INEXACT (1 << 5)
FE_INEXACT
};
#define FE_ALL_EXCEPT \
(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
/* The ix87 FPU supports all of the four defined rounding modes. We
/* The Sparc FPU supports all of the four defined rounding modes. We
use again the bit positions in the FPU control word as the values
for the appropriate macros. */
enum
{
FE_TONEAREST = 0,
#define FE_TONEAREST FE_TONEAREST
FE_DOWNWARD = 0x400,
#define FE_DOWNWARD FE_DOWNWARD
FE_UPWARD = 0x800,
#define FE_UPWARD FE_UPWARD
FE_TOWARDZERO = 0xc00
#define FE_TOWARDZERO FE_TOWARDZERO
FE_TONEAREST =
#define FE_TONEAREST (0 << 30)
FE_TONEAREST,
FE_TOWARDZERO =
#define FE_TOWARDZERO (1 << 30)
FE_TOWARDZERO,
FE_UPWARD =
#define FE_UPWARD (-0x7fffffff - 1) /* (2 << 30) */
FE_UPWARD,
FE_DOWNWARD =
#define FE_DOWNWARD (-0x40000000) /* (3 << 30) */
FE_DOWNWARD
};
#define __FE_ROUND_MASK (3U << 30)
/* Type representing exception flags. */
typedef unsigned short int fexcept_t;
typedef unsigned long int fexcept_t;
/* Type representing floating-point environment. This structure
corresponds to the layout of the block written by the `fstenv'
instruction and has additional fields for the contents of the MXCSR
register as written by the `stmxcsr' instruction. */
typedef struct
{
unsigned short int __control_word;
unsigned short int __unused1;
unsigned short int __status_word;
unsigned short int __unused2;
unsigned short int __tags;
unsigned short int __unused3;
unsigned int __eip;
unsigned short int __cs_selector;
unsigned int __opcode:11;
unsigned int __unused4:5;
unsigned int __data_offset;
unsigned short int __data_selector;
unsigned short int __unused5;
#ifdef __x86_64__
unsigned int __mxcsr;
#endif
}
fenv_t;
/* Type representing floating-point environment. */
typedef unsigned long int fenv_t;
/* If the default argument is used we use this value. */
#define FE_DFL_ENV ((const fenv_t *) -1)
@ -92,3 +83,6 @@ fenv_t;
# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
/* For internal use only: access the fp state register. */
# define __fenv_stfsr(X) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (X))
# define __fenv_ldfsr(X) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (X))

View File

@ -0,0 +1,97 @@
/* Macros to control TS 18661-3 glibc features on ldbl-128 platforms.
Copyright (C) 2017-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _BITS_FLOATN_H
#define _BITS_FLOATN_H
#include <features.h>
#include <bits/long-double.h>
/* Defined to 1 if the current compiler invocation provides a
floating-point type with the IEEE 754 binary128 format, and this
glibc includes corresponding *f128 interfaces for it. */
#ifndef __NO_LONG_DOUBLE_MATH
# define __HAVE_FLOAT128 1
#else
/* glibc does not support _Float128 for platforms where long double is
normally binary128 when building with long double as binary64.
GCC's default for supported scalar modes does not support it either
in that case. */
# define __HAVE_FLOAT128 0
#endif
/* Defined to 1 if __HAVE_FLOAT128 is 1 and the type is ABI-distinct
from the default float, double and long double types in this glibc. */
#define __HAVE_DISTINCT_FLOAT128 0
/* Defined to 1 if the current compiler invocation provides a
floating-point type with the right format for _Float64x, and this
glibc includes corresponding *f64x interfaces for it. */
#define __HAVE_FLOAT64X __HAVE_FLOAT128
/* Defined to 1 if __HAVE_FLOAT64X is 1 and _Float64x has the format
of long double. Otherwise, if __HAVE_FLOAT64X is 1, _Float64x has
the format of _Float128, which must be different from that of long
double. */
#define __HAVE_FLOAT64X_LONG_DOUBLE __HAVE_FLOAT128
#ifndef __ASSEMBLER__
/* Defined to concatenate the literal suffix to be used with _Float128
types, if __HAVE_FLOAT128 is 1. */
# if __HAVE_FLOAT128
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
/* The literal suffix f128 exists only since GCC 7.0. */
# define __f128(x) x##l
# else
# define __f128(x) x##f128
# endif
# endif
/* Defined to a complex binary128 type if __HAVE_FLOAT128 is 1. */
# if __HAVE_FLOAT128
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
# define __CFLOAT128 _Complex long double
# else
# define __CFLOAT128 _Complex _Float128
# endif
# endif
/* The remaining of this file provides support for older compilers. */
# if __HAVE_FLOAT128
/* The type _Float128 exists only since GCC 7.0. */
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef long double _Float128;
# endif
/* Various built-in functions do not exist before GCC 7.0. */
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf128() (__builtin_huge_vall ())
# define __builtin_inff128() (__builtin_infl ())
# define __builtin_nanf128(x) (__builtin_nanl (x))
# define __builtin_nansf128(x) (__builtin_nansl (x))
# endif
# endif
#endif /* !__ASSEMBLER__. */
#include <bits/floatn-common.h>
#endif /* _BITS_FLOATN_H */

View File

@ -0,0 +1,51 @@
/* Defines for bits in AT_HWCAP.
Copyright (C) 2011-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#if !defined(_SYS_AUXV_H) && !defined(_SYSDEPS_SYSDEP_H)
# error "Never include <bits/hwcap.h> directly; use <sys/auxv.h> instead."
#endif
#define HWCAP_SPARC_FLUSH 0x00000001
#define HWCAP_SPARC_STBAR 0x00000002
#define HWCAP_SPARC_SWAP 0x00000004
#define HWCAP_SPARC_MULDIV 0x00000008
#define HWCAP_SPARC_V9 0x00000010
#define HWCAP_SPARC_ULTRA3 0x00000020
#define HWCAP_SPARC_BLKINIT 0x00000040
#define HWCAP_SPARC_N2 0x00000080
#define HWCAP_SPARC_MUL32 0x00000100
#define HWCAP_SPARC_DIV32 0x00000200
#define HWCAP_SPARC_FSMULD 0x00000400
#define HWCAP_SPARC_V8PLUS 0x00000800
#define HWCAP_SPARC_POPC 0x00001000
#define HWCAP_SPARC_VIS 0x00002000
#define HWCAP_SPARC_VIS2 0x00004000
#define HWCAP_SPARC_ASI_BLK_INIT 0x00008000
#define HWCAP_SPARC_FMAF 0x00010000
#define HWCAP_SPARC_VIS3 0x00020000
#define HWCAP_SPARC_HPC 0x00040000
#define HWCAP_SPARC_RANDOM 0x00080000
#define HWCAP_SPARC_TRANS 0x00100000
#define HWCAP_SPARC_FJFMAU 0x00200000
#define HWCAP_SPARC_IMA 0x00400000
#define HWCAP_SPARC_ASI_CACHE_SPARING \
0x00800000
#define HWCAP_SPARC_PAUSE 0x01000000
#define HWCAP_SPARC_CBCOND 0x02000000
#define HWCAP_SPARC_CRYPTO 0x04000000
#define HWCAP_SPARC_ADP 0x08000000

View File

@ -0,0 +1,20 @@
/* Properties of long double type. ldbl-128 version.
Copyright (C) 2016-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* long double is distinct from double, so there is nothing to
define here. */

View File

@ -0,0 +1,235 @@
//#if !defined __ASSEMBLER__ && !defined _ISOMAC && !defined __OPTIMIZE__
//# error "glibc cannot be compiled without optimization"
//#endif
/* Another evil option when it comes to compiling the C library is
--ffast-math since it alters the ABI. */
#if defined __FAST_MATH__ && !defined TEST_FAST_MATH
# error "glibc must not be compiled with -ffast-math"
#endif
/* Define if using GNU ld, with support for weak symbols in a.out,
and for symbol set and warning messages extensions in a.out and ELF.
This implies HAVE_WEAK_SYMBOLS; set by --with-gnu-ld. */
#define HAVE_GNU_LD 1
/* Define if using ELF, which supports weak symbols.
This implies HAVE_ASM_WEAK_DIRECTIVE set by --with-elf. */
#define HAVE_ELF 1
/* Define if using XCOFF. Set by --with-xcoff. */
#undef HAVE_XCOFF
/* Define if weak symbols are available via the `.weak' directive. */
#define HAVE_ASM_WEAK_DIRECTIVE 1
/* Define if weak symbols are available via the `.weakext' directive. */
#undef HAVE_ASM_WEAKEXT_DIRECTIVE
/* Define to the assembler line separator character for multiple
assembler instructions per line. Default is `;' */
#undef ASM_LINE_SEP
/* Define if not using ELF, but `.init' and `.fini' sections are available. */
#undef HAVE_INITFINI
/* Define if __attribute__((section("foo"))) puts quotes around foo. */
/*#define HAVE_SECTION_QUOTES 1
[zooey]: defining this causes assembler errors, and I don't think
that any BeOS-gcc actually produces quotes in sections...
*/
#undef HAVE_SECTION_QUOTES
/* Define if using the GNU assembler, gas. */
#define HAVE_GNU_AS 1
/* Define if the assembler supports the `.set' directive. */
#define HAVE_ASM_SET_DIRECTIVE 1
/* Define to the name of the assembler's directive for
declaring a symbol global (default `.globl'). */
#define ASM_GLOBAL_DIRECTIVE .globl
/* Define to the prefix before `object' or `function' in the
assembler's `.type' directive, if it has one. */
#undef ASM_TYPE_DIRECTIVE_PREFIX
/* Define a symbol_name as a global .symbol_name for ld. */
#undef HAVE_ASM_GLOBAL_DOT_NAME
/* Define if the assembler generates debugging information directly. */
#undef HAVE_CPP_ASM_DEBUGINFO
/* Define if _Unwind_Find_FDE should be exported from glibc. */
#undef EXPORT_UNWIND_FIND_FDE
/* Define to use GNU libio instead of GNU stdio.
This is defined by configure under --enable-libio. */
#define USE_IN_LIBIO 1
/* Define if using ELF and the assembler supports the `.previous'
directive. */
#define HAVE_ASM_PREVIOUS_DIRECTIVE 1
/* Define if using ELF and the assembler supports the `.popsection'
directive. */
#undef HAVE_ASM_POPSECTION_DIRECTIVE
/* Define if versioning of the library is wanted. */
#undef DO_VERSIONING
/* Defined to the oldest ABI we support, like 2.1. */
#undef GLIBC_OLDEST_ABI
/* Define if static NSS modules are wanted. */
#undef DO_STATIC_NSS
/* Define if gcc uses DWARF2 unwind information for exception support. */
#define HAVE_DWARF2_UNWIND_INFO 1
/* Define if gcc uses DWARF2 unwind information for exception support
with static variable. */
#define HAVE_DWARF2_UNWIND_INFO_STATIC 1
/* Define if the compiler supports __builtin_expect. */
#undef HAVE_BUILTIN_EXPECT
/* Define if the compiler supports __builtin_memset. */
#undef HAVE_BUILTIN_MEMSET
/* Define if the __thread keyword is supported. */
#undef HAVE___THREAD
/* Define if the compiler supports __attribute__((tls_model(""))). */
#undef HAVE_TLS_MODEL_ATTRIBUTE
/* Define if the regparm attribute shall be used for local functions
(gcc on ix86 only). */
#define USE_REGPARMS 0
/* Defined on PowerPC if the GCC being used has a problem with clobbering
certain registers (CR0, MQ, CTR, LR) in asm statements. */
#undef BROKEN_PPC_ASM_CR0
/* Defined on SPARC if ld doesn't handle R_SPARC_WDISP22 against .hidden
symbol. sysdeps/sparc/sparc32/elf/configure. */
#undef BROKEN_SPARC_WDISP22
/* Define if the linker supports the -z combreloc option. */
#undef HAVE_Z_COMBRELOC
/* Define if the assembler supported .protected. */
#undef HAVE_PROTECTED
/* Define if the assembler supported .hidden. */
#undef HAVE_HIDDEN
/* Define if the compiler supports __attribute__ ((visibility (...))). */
#undef HAVE_VISIBILITY_ATTRIBUTE
/* Define if the compiler doesn't support __attribute__ ((visibility (...)))
together with __asm__ redirection properly. */
#undef HAVE_BROKEN_VISIBILITY_ATTRIBUTE
/* Define if the compiler doesn't support __attribute__ ((alias (...)))
together with __asm__ redirection properly. */
#undef HAVE_BROKEN_ALIAS_ATTRIBUTE
/* Define if _rtld_local structure should be forced into .sdata section. */
#undef HAVE_SDATA_SECTION
/* Define if binutils support TLS handling. */
#undef HAVE_TLS_SUPPORT
/* Define if the linker supports .preinit_array/.init_array/.fini_array
sections. */
#undef HAVE_INITFINI_ARRAY
/* Define if the access to static and hidden variables is position independent
and does not need relocations. */
#undef PI_STATIC_AND_HIDDEN
/* Define this to disable the `hidden_proto' et al macros in
include/libc-symbols.h that avoid PLT slots in the shared objects. */
#undef NO_HIDDEN
/* Defined to some form of __attribute__ ((...)) if the compiler supports
a different, more efficient calling convention. */
#if USE_REGPARMS && !defined PROF && !defined __BOUNDED_POINTERS__
# define internal_function __attribute__ ((regparm (3), stdcall))
#endif
/* Linux specific: minimum supported kernel version. */
#undef __LINUX_KERNEL_VERSION
/* Override abi-tags ABI version if necessary. */
#undef __ABI_TAG_VERSION
/* An extension in gcc 2.96 and up allows the subtraction of two
local labels. */
#undef HAVE_SUBTRACT_LOCAL_LABELS
/* bash 2.0 introduced the _XXX_GNU_nonoption_argv_flags_ variable to help
getopt determine whether a parameter is a flag or not. This features
was disabled later since it caused trouble. We are by default therefore
disabling the support as well. */
#undef USE_NONOPTION_FLAGS
/* Mach/Hurd specific: define if mig supports the `retcode' keyword. */
#undef HAVE_MIG_RETCODE
/* Mach specific: define if the `host_page_size' RPC is available. */
#undef HAVE_HOST_PAGE_SIZE
/* Mach/i386 specific: define if the `i386_io_perm_*' RPCs are available. */
#undef HAVE_I386_IO_PERM_MODIFY
/* Mach/i386 specific: define if the `i386_set_gdt' RPC is available. */
#undef HAVE_I386_SET_GDT
/*
*/
#ifndef _LIBC
/* These symbols might be defined by some sysdeps configures.
They are used only in miscellaneous generator programs, not
in compiling libc itself. */
/* sysdeps/generic/configure.in */
#undef HAVE_PSIGNAL
/* sysdeps/unix/configure.in */
#define HAVE_STRERROR
/* sysdeps/unix/common/configure.in */
#undef HAVE_SYS_SIGLIST
#undef HAVE__SYS_SIGLIST
#undef HAVE__CTYPE_
#undef HAVE___CTYPE_
#undef HAVE___CTYPE
#undef HAVE__CTYPE__
#undef HAVE__CTYPE
#undef HAVE__LOCP
#endif
/*
*/
#ifdef _LIBC
/* The zic and zdump programs need these definitions. */
#define HAVE_STRERROR 1
/* The locale code needs these definitions. */
#define HAVE_REGEX 1
//#define HAVE_MMAP 1
#undef HAVE_MMAP
#endif

View File

@ -0,0 +1,172 @@
#ifndef FENV_PRIVATE_H
#define FENV_PRIVATE_H 1
#include <fenv.h>
static __always_inline void
libc_fesetround (int r)
{
fenv_t etmp;
__fenv_stfsr(etmp);
etmp = (etmp & ~__FE_ROUND_MASK) | (r);
__fenv_ldfsr(etmp);
}
static __always_inline void
libc_feholdexcept_setround (fenv_t *e, int r)
{
fenv_t etmp;
__fenv_stfsr(etmp);
*(e) = etmp;
etmp = etmp & ~((0x1f << 23) | FE_ALL_EXCEPT);
etmp = (etmp & ~__FE_ROUND_MASK) | (r);
__fenv_ldfsr(etmp);
}
static __always_inline int
libc_fetestexcept (int e)
{
fenv_t etmp;
__fenv_stfsr(etmp);
return etmp & (e) & FE_ALL_EXCEPT;
}
static __always_inline void
libc_fesetenv (fenv_t *e)
{
__fenv_ldfsr(*e);
}
static __always_inline int
libc_feupdateenv_test (fenv_t *e, int ex)
{
fenv_t etmp;
__fenv_stfsr(etmp);
etmp &= FE_ALL_EXCEPT;
__fenv_ldfsr(*e);
__feraiseexcept (etmp);
return etmp & ex;
}
static __always_inline void
libc_feupdateenv (fenv_t *e)
{
libc_feupdateenv_test (e, 0);
}
static __always_inline void
libc_feholdsetround (fenv_t *e, int r)
{
fenv_t etmp;
__fenv_stfsr(etmp);
*(e) = etmp;
etmp = (etmp & ~__FE_ROUND_MASK) | (r);
__fenv_ldfsr(etmp);
}
static __always_inline void
libc_feresetround (fenv_t *e)
{
fenv_t etmp;
__fenv_stfsr(etmp);
etmp = (etmp & ~__FE_ROUND_MASK) | (*e & __FE_ROUND_MASK);
__fenv_ldfsr(etmp);
}
#define libc_feholdexceptf libc_feholdexcept
#define libc_fesetroundf libc_fesetround
#define libc_feholdexcept_setroundf libc_feholdexcept_setround
#define libc_fetestexceptf libc_fetestexcept
#define libc_fesetenvf libc_fesetenv
#define libc_feupdateenv_testf libc_feupdateenv_test
#define libc_feupdateenvf libc_feupdateenv
#define libc_feholdsetroundf libc_feholdsetround
#define libc_feresetroundf libc_feresetround
#define libc_feholdexcept libc_feholdexcept
#define libc_fesetround libc_fesetround
#define libc_feholdexcept_setround libc_feholdexcept_setround
#define libc_fetestexcept libc_fetestexcept
#define libc_fesetenv libc_fesetenv
#define libc_feupdateenv_test libc_feupdateenv_test
#define libc_feupdateenv libc_feupdateenv
#define libc_feholdsetround libc_feholdsetround
#define libc_feresetround libc_feresetround
#define libc_feholdexceptl libc_feholdexcept
#define libc_fesetroundl libc_fesetround
#define libc_feholdexcept_setroundl libc_feholdexcept_setround
#define libc_fetestexceptl libc_fetestexcept
#define libc_fesetenvl libc_fesetenv
#define libc_feupdateenv_testl libc_feupdateenv_test
#define libc_feupdateenvl libc_feupdateenv
#define libc_feholdsetroundl libc_feholdsetround
#define libc_feresetroundl libc_feresetround
/* We have support for rounding mode context. */
#define HAVE_RM_CTX 1
static __always_inline void
libc_feholdexcept_setround_sparc_ctx (struct rm_ctx *ctx, int round)
{
fenv_t new;
__fenv_stfsr(ctx->env);
new = ctx->env & ~((0x1f << 23) | FE_ALL_EXCEPT);
new = (new & ~__FE_ROUND_MASK) | round;
if (__glibc_unlikely (new != ctx->env))
{
__fenv_ldfsr(new);
ctx->updated_status = true;
}
else
ctx->updated_status = false;
}
static __always_inline void
libc_fesetenv_sparc_ctx (struct rm_ctx *ctx)
{
libc_fesetenv(&ctx->env);
}
static __always_inline void
libc_feupdateenv_sparc_ctx (struct rm_ctx *ctx)
{
if (__glibc_unlikely (ctx->updated_status))
libc_feupdateenv_test (&ctx->env, 0);
}
static __always_inline void
libc_feholdsetround_sparc_ctx (struct rm_ctx *ctx, int round)
{
fenv_t new;
__fenv_stfsr(ctx->env);
new = (ctx->env & ~__FE_ROUND_MASK) | round;
if (__glibc_unlikely (new != ctx->env))
{
__fenv_ldfsr(new);
ctx->updated_status = true;
}
else
ctx->updated_status = false;
}
#define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_sparc_ctx
#define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_sparc_ctx
#define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_sparc_ctx
#define libc_fesetenv_ctx libc_fesetenv_sparc_ctx
#define libc_fesetenvf_ctx libc_fesetenv_sparc_ctx
#define libc_fesetenvl_ctx libc_fesetenv_sparc_ctx
#define libc_feupdateenv_ctx libc_feupdateenv_sparc_ctx
#define libc_feupdateenvf_ctx libc_feupdateenv_sparc_ctx
#define libc_feupdateenvl_ctx libc_feupdateenv_sparc_ctx
#define libc_feresetround_ctx libc_feupdateenv_sparc_ctx
#define libc_feresetroundf_ctx libc_feupdateenv_sparc_ctx
#define libc_feresetroundl_ctx libc_feupdateenv_sparc_ctx
#define libc_feholdsetround_ctx libc_feholdsetround_sparc_ctx
#define libc_feholdsetroundf_ctx libc_feholdsetround_sparc_ctx
#define libc_feholdsetroundl_ctx libc_feholdsetround_sparc_ctx
#endif /* FENV_PRIVATE_H */

View File

@ -0,0 +1,79 @@
/* Check for underflow and force underflow exceptions.
Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _MATH_UNDERFLOW_H
#define _MATH_UNDERFLOW_H 1
#include <float.h>
#include <math.h>
#include <math-barriers.h>
#define fabs_tg(x) __MATH_TG ((x), (__typeof (x)) __builtin_fabs, (x))
/* These must be function-like macros because some __MATH_TG
implementations macro-expand the function-name argument before
concatenating a suffix to it. */
#define min_of_type_f() FLT_MIN
#define min_of_type_() DBL_MIN
#define min_of_type_l() LDBL_MIN
#define min_of_type_f128() FLT128_MIN
#define min_of_type(x) __MATH_TG ((x), (__typeof (x)) min_of_type_, ())
/* If X (which is not a NaN) is subnormal, force an underflow
exception. */
#define math_check_force_underflow(x) \
do \
{ \
__typeof (x) force_underflow_tmp = (x); \
if (fabs_tg (force_underflow_tmp) \
< min_of_type (force_underflow_tmp)) \
{ \
__typeof (force_underflow_tmp) force_underflow_tmp2 \
= force_underflow_tmp * force_underflow_tmp; \
math_force_eval (force_underflow_tmp2); \
} \
} \
while (0)
/* Likewise, but X is also known to be nonnegative. */
#define math_check_force_underflow_nonneg(x) \
do \
{ \
__typeof (x) force_underflow_tmp = (x); \
if (force_underflow_tmp \
< min_of_type (force_underflow_tmp)) \
{ \
__typeof (force_underflow_tmp) force_underflow_tmp2 \
= force_underflow_tmp * force_underflow_tmp; \
math_force_eval (force_underflow_tmp2); \
} \
} \
while (0)
/* Likewise, for both real and imaginary parts of a complex
result. */
#define math_check_force_underflow_complex(x) \
do \
{ \
__typeof (x) force_underflow_complex_tmp = (x); \
math_check_force_underflow (__real__ force_underflow_complex_tmp); \
math_check_force_underflow (__imag__ force_underflow_complex_tmp); \
} \
while (0)
#endif /* math-underflow.h */

View File

@ -1,4 +1,120 @@
#ifndef _MATH_PRIVATE_H_
#error "Never use <math_ldbl.h> directly; include <math_private.h> instead."
/* Manipulation of the bit representation of 'long double' quantities.
Copyright (C) 1999-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _MATH_LDBL_H_
#define _MATH_LDBL_H_ 1
#include <stdint.h>
#include <endian.h>
/* A union which permits us to convert between a long double and
four 32 bit ints or two 64 bit ints. */
#if __FLOAT_WORD_ORDER == __BIG_ENDIAN
typedef union
{
long double value;
struct
{
uint64_t msw;
uint64_t lsw;
} parts64;
struct
{
uint32_t w0, w1, w2, w3;
} parts32;
} ieee854_long_double_shape_type;
#endif
#if __FLOAT_WORD_ORDER == __LITTLE_ENDIAN
typedef union
{
long double value;
struct
{
uint64_t lsw;
uint64_t msw;
} parts64;
struct
{
uint32_t w3, w2, w1, w0;
} parts32;
} ieee854_long_double_shape_type;
#endif
/* Get two 64 bit ints from a long double. */
#define GET_LDOUBLE_WORDS64(ix0,ix1,d) \
do { \
ieee854_long_double_shape_type qw_u; \
qw_u.value = (d); \
(ix0) = qw_u.parts64.msw; \
(ix1) = qw_u.parts64.lsw; \
} while (0)
/* Set a long double from two 64 bit ints. */
#define SET_LDOUBLE_WORDS64(d,ix0,ix1) \
do { \
ieee854_long_double_shape_type qw_u; \
qw_u.parts64.msw = (ix0); \
qw_u.parts64.lsw = (ix1); \
(d) = qw_u.value; \
} while (0)
/* Get the more significant 64 bits of a long double mantissa. */
#define GET_LDOUBLE_MSW64(v,d) \
do { \
ieee854_long_double_shape_type sh_u; \
sh_u.value = (d); \
(v) = sh_u.parts64.msw; \
} while (0)
/* Set the more significant 64 bits of a long double mantissa from an int. */
#define SET_LDOUBLE_MSW64(d,v) \
do { \
ieee854_long_double_shape_type sh_u; \
sh_u.value = (d); \
sh_u.parts64.msw = (v); \
(d) = sh_u.value; \
} while (0)
/* Get the least significant 64 bits of a long double mantissa. */
#define GET_LDOUBLE_LSW64(v,d) \
do { \
ieee854_long_double_shape_type sh_u; \
sh_u.value = (d); \
(v) = sh_u.parts64.lsw; \
} while (0)
/*
On a platform already supporting a binary128 long double,
_Float128 will alias to long double. This transformation
makes aliasing *l functions to *f128 trivial.
*/
#define _Float128 long double
#define L(x) x##L
#endif /* math_ldbl.h */

View File

@ -0,0 +1,87 @@
/* Copyright (C) 2011-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include_next <sysdep.h>
#define _SYSDEPS_SYSDEP_H 1
#include <bits/hwcap.h>
#ifdef __ASSEMBLER__
#define SPARC_PIC_THUNK(reg) \
.ifndef __sparc_get_pc_thunk.reg; \
.section .text.__sparc_get_pc_thunk.reg,"axG",@progbits,__sparc_get_pc_thunk.reg,comdat; \
.align 32; \
.weak __sparc_get_pc_thunk.reg; \
.hidden __sparc_get_pc_thunk.reg; \
.type __sparc_get_pc_thunk.reg, #function; \
__sparc_get_pc_thunk.reg: \
jmp %o7 + 8; \
add %o7, %reg, %##reg; \
.previous; \
.endif;
/* The "-4" and "+4" offsets against _GLOBAL_OFFSET_TABLE_ are
critical since they represent the offset from the thunk call to the
instruction containing the _GLOBAL_OFFSET_TABLE_ reference.
Therefore these instructions cannot be moved around without
appropriate adjustments to those offsets.
Furthermore, these expressions are special in another regard. When
the assembler sees a reference to _GLOBAL_OFFSET_TABLE_ inside of
a %hi() or %lo(), it emits a PC-relative relocation. This causes
R_SPARC_HI22 to turn into R_SPARC_PC22, and R_SPARC_LO10 to turn into
R_SPARC_PC10, respectively.
Even when v9 we use a call sequence instead of using "rd %pc" because
RDPC is extremely expensive and incurs a full pipeline flush. */
#define SPARC_PIC_THUNK_CALL(reg) \
sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %##reg; \
call __sparc_get_pc_thunk.reg; \
or %##reg, %lo(_GLOBAL_OFFSET_TABLE_+4), %##reg;
#define SETUP_PIC_REG(reg) \
SPARC_PIC_THUNK(reg) \
SPARC_PIC_THUNK_CALL(reg)
#define SETUP_PIC_REG_LEAF(reg, tmp) \
SPARC_PIC_THUNK(reg) \
mov %o7, %##tmp; \
SPARC_PIC_THUNK_CALL(reg); \
mov %##tmp, %o7;
#undef ENTRY
#define ENTRY(name) \
.align 4; \
.global C_SYMBOL_NAME(name); \
.type name, @function; \
C_LABEL(name) \
cfi_startproc;
#undef END
#define END(name) \
cfi_endproc;
#undef LOC
#define LOC(name) .L##name
#endif /* __ASSEMBLER__ */
/* This is the offset from the %sp to the backing store above the
* register windows. So if you poke stack memory directly you add this. */
#define STACK_BIAS 2047

View File

@ -0,0 +1,121 @@
/* Macros to control TS 18661-3 glibc features on x86.
Copyright (C) 2017-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _BITS_FLOATN_H
#define _BITS_FLOATN_H
#include <features.h>
/* Defined to 1 if the current compiler invocation provides a
floating-point type with the IEEE 754 binary128 format, and this
glibc includes corresponding *f128 interfaces for it. The required
libgcc support was added some time after the basic compiler
support, for x86_64 and x86. */
#if (defined __x86_64__ \
? __GNUC_PREREQ (4, 3) \
: (defined __GNU__ ? __GNUC_PREREQ (4, 5) : __GNUC_PREREQ (4, 4)))
# define __HAVE_FLOAT128 1
#else
# define __HAVE_FLOAT128 0
#endif
/* Defined to 1 if __HAVE_FLOAT128 is 1 and the type is ABI-distinct
from the default float, double and long double types in this glibc. */
#if __HAVE_FLOAT128
# define __HAVE_DISTINCT_FLOAT128 1
#else
# define __HAVE_DISTINCT_FLOAT128 0
#endif
/* Defined to 1 if the current compiler invocation provides a
floating-point type with the right format for _Float64x, and this
glibc includes corresponding *f64x interfaces for it. */
#define __HAVE_FLOAT64X 1
/* Defined to 1 if __HAVE_FLOAT64X is 1 and _Float64x has the format
of long double. Otherwise, if __HAVE_FLOAT64X is 1, _Float64x has
the format of _Float128, which must be different from that of long
double. */
#define __HAVE_FLOAT64X_LONG_DOUBLE 1
#ifndef __ASSEMBLER__
/* Defined to concatenate the literal suffix to be used with _Float128
types, if __HAVE_FLOAT128 is 1. */
# if __HAVE_FLOAT128
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
/* The literal suffix f128 exists only since GCC 7.0. */
# define __f128(x) x##q
# else
# define __f128(x) x##f128
# endif
# endif
/* Defined to a complex binary128 type if __HAVE_FLOAT128 is 1. */
# if __HAVE_FLOAT128
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
/* Add a typedef for older GCC compilers which don't natively support
_Complex _Float128. */
typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
# define __CFLOAT128 __cfloat128
# else
# define __CFLOAT128 _Complex _Float128
# endif
# endif
/* The remaining of this file provides support for older compilers. */
# if __HAVE_FLOAT128
/* The type _Float128 exists only since GCC 7.0. */
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef __float128 _Float128;
# endif
/* __builtin_huge_valf128 doesn't exist before GCC 7.0. */
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf128() ((_Float128) __builtin_huge_val ())
# endif
/* Older GCC has only a subset of built-in functions for _Float128 on
x86, and __builtin_infq is not usable in static initializers.
Converting a narrower sNaN to _Float128 produces a quiet NaN, so
attempts to use _Float128 sNaNs will not work properly with older
compilers. */
# if !__GNUC_PREREQ (7, 0)
# define __builtin_copysignf128 __builtin_copysignq
# define __builtin_fabsf128 __builtin_fabsq
# define __builtin_inff128() ((_Float128) __builtin_inf ())
# define __builtin_nanf128(x) ((_Float128) __builtin_nan (x))
# define __builtin_nansf128(x) ((_Float128) __builtin_nans (x))
# endif
/* In math/math.h, __MATH_TG will expand signbit to __builtin_signbit*,
e.g.: __builtin_signbitf128, before GCC 6. However, there has never
been a __builtin_signbitf128 in GCC and the type-generic builtin is
only available since GCC 6. */
# if !__GNUC_PREREQ (6, 0)
# define __builtin_signbitf128 __signbitf128
# endif
# endif
#endif /* !__ASSEMBLER__. */
#include <bits/floatn-common.h>
#endif /* _BITS_FLOATN_H */

View File

@ -0,0 +1,39 @@
/* Properties of long double type.
Copyright (C) 2016-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* This header is included by <sys/cdefs.h>.
If long double is ABI-compatible with double, it should define
__NO_LONG_DOUBLE_MATH to 1; otherwise, it should leave
__NO_LONG_DOUBLE_MATH undefined.
If this build of the GNU C Library supports both long double
ABI-compatible with double and some other long double format not
ABI-compatible with double, it should define
__LONG_DOUBLE_MATH_OPTIONAL to 1; otherwise, it should leave
__LONG_DOUBLE_MATH_OPTIONAL undefined.
If __NO_LONG_DOUBLE_MATH is already defined, this header must not
define anything; this is needed to work with the definition of
__NO_LONG_DOUBLE_MATH in nldbl-compat.h. */
/* In the default version of this header, long double is
ABI-compatible with double. */
#ifndef __NO_LONG_DOUBLE_MATH
# define __NO_LONG_DOUBLE_MATH 1
#endif

View File

@ -23,6 +23,7 @@
#ifndef _FENV_H
#define _FENV_H 1
#include <stdbool.h>
#include <features.h>
/* Get the architecture dependend definitions. The following definitions
@ -133,4 +134,13 @@ extern int fegetexcept (void) __THROW;
__END_DECLS
/* Rounding mode context. This allows functions to set/restore rounding mode
* only when the desired rounding mode is different from the current rounding
* mode. */
struct rm_ctx
{
fenv_t env;
bool updated_status;
};
#endif /* fenv.h */

View File

@ -0,0 +1,37 @@
/* Control when floating-point expressions are evaluated. Generic version.
Copyright (C) 2007-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _MATH_BARRIERS_H
#define _MATH_BARRIERS_H 1
/* math_opt_barrier evaluates and returns its floating-point argument
and ensures that the evaluation of any expression using the result
of math_opt_barrier is not moved before the call. math_force_eval
ensures that its floating-point argument is evaluated for its side
effects even if its value is apparently unused, and that the
evaluation of its argument is not moved after the call. Both these
macros are used to ensure the correct ordering of floating-point
expression evaluations with respect to accesses to the
floating-point environment. */
#define math_opt_barrier(x) \
({ __typeof (x) __x = (x); __asm ("" : "+m" (__x)); __x; })
#define math_force_eval(x) \
({ __typeof (x) __x = (x); __asm __volatile__ ("" : : "m" (__x)); })
#endif /* math-barriers.h */

View File

@ -126,6 +126,71 @@ extern int signgam;
#endif
/* Depending on the type of TG_ARG, call an appropriately suffixed
version of FUNC with arguments (including parentheses) ARGS.
Suffixed functions may not exist for long double if it has the same
format as double, or for other types with the same format as float,
double or long double. The behavior is undefined if the argument
does not have a real floating type. The definition may use a
conditional expression, so all suffixed versions of FUNC must
return the same type (FUNC may include a cast if necessary rather
than being a single identifier). */
#ifdef __NO_LONG_DOUBLE_MATH
# if __HAVE_DISTINCT_FLOAT128
# error "Distinct _Float128 without distinct long double not supported."
# endif
# define __MATH_TG(TG_ARG, FUNC, ARGS) \
(sizeof (TG_ARG) == sizeof (float) ? FUNC ## f ARGS : FUNC ARGS)
#elif __HAVE_DISTINCT_FLOAT128
# if __HAVE_GENERIC_SELECTION
# if __HAVE_FLOATN_NOT_TYPEDEF && __HAVE_FLOAT32
# define __MATH_TG_F32(FUNC, ARGS) _Float32: FUNC ## f ARGS,
# else
# define __MATH_TG_F32(FUNC, ARGS)
# endif
# if __HAVE_FLOATN_NOT_TYPEDEF && __HAVE_FLOAT64X
# if __HAVE_FLOAT64X_LONG_DOUBLE
# define __MATH_TG_F64X(FUNC, ARGS) _Float64x: FUNC ## l ARGS,
# else
# define __MATH_TG_F64X(FUNC, ARGS) _Float64x: FUNC ## f128 ARGS,
# endif
# else
# define __MATH_TG_F64X(FUNC, ARGS)
# endif
# define __MATH_TG(TG_ARG, FUNC, ARGS) \
_Generic ((TG_ARG), \
float: FUNC ## f ARGS, \
__MATH_TG_F32 (FUNC, ARGS) \
default: FUNC ARGS, \
long double: FUNC ## l ARGS, \
__MATH_TG_F64X (FUNC, ARGS) \
_Float128: FUNC ## f128 ARGS)
# else
# if __HAVE_FLOATN_NOT_TYPEDEF
# error "Non-typedef _FloatN but no _Generic."
# endif
# define __MATH_TG(TG_ARG, FUNC, ARGS) \
__builtin_choose_expr \
(__builtin_types_compatible_p (__typeof (TG_ARG), float), \
FUNC ## f ARGS, \
__builtin_choose_expr \
(__builtin_types_compatible_p (__typeof (TG_ARG), double), \
FUNC ARGS, \
__builtin_choose_expr \
(__builtin_types_compatible_p (__typeof (TG_ARG), long double), \
FUNC ## l ARGS, \
FUNC ## f128 ARGS)))
# endif
#else
# define __MATH_TG(TG_ARG, FUNC, ARGS) \
(sizeof (TG_ARG) == sizeof (float) \
? FUNC ## f ARGS \
: sizeof (TG_ARG) == sizeof (double) \
? FUNC ARGS \
: FUNC ## l ARGS)
#endif
/* ISO C99 defines some generic macros which work on any data type. */
#if __USE_ISOC99
@ -247,6 +312,25 @@ enum
#endif /* Use ISO C99. */
/* Return nonzero value if X is a signaling NaN. */
# ifndef __cplusplus
# define issignaling(x) __MATH_TG ((x), __issignaling, (x))
# else
/* In C++ mode, __MATH_TG cannot be used, because it relies on
__builtin_types_compatible_p, which is a C-only builtin. */
# ifdef __NO_LONG_DOUBLE_MATH
# define issignaling(x) \
(sizeof (x) == sizeof (float) ? __issignalingf (x) : __issignaling (x))
# else
# define issignaling(x) \
(sizeof (x) == sizeof (float) \
? __issignalingf (x) \
: sizeof (x) == sizeof (double) \
? __issignaling (x) : __issignalingl (x))
# endif
# endif
#ifdef __USE_MISC
/* Support for various different standard error handling behaviors. */
typedef enum

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2011-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gmail.com>, 2011.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#define NO_MATH_REDIRECT
#include <math.h>
#include <math_private.h>
#include <libm-alias-ldouble.h>
/* wrapper sqrtl */
long double
__sqrtl (long double x)
{
return __ieee754_sqrtl (x);
}
libm_alias_ldouble (__sqrt, sqrt)