Issue #1291 - Part 3: Update fdlibm to Sept 2019 version

This commit is contained in:
wolfbeast 2019-11-15 15:17:01 +01:00 committed by Roy Tam
commit ddb1aaaee3
16 changed files with 163 additions and 102 deletions

View file

@ -9,9 +9,11 @@ resources.
The in-tree copy is updated by running
sh update.sh
or
sh update.sh <sha-commit>
from within the modules/fdlibm directory.
Current version: [commit f2287da07ac7a26ac08745cac66eec82ab9ba384].
Current version: [commit cf4707bb2f78ecf56ba350bdc24e3135b4339622 (2019-09-25T18:50:57Z)].
patches 01-14 fixes files to be usable within mozilla-central tree.
patches 01-18 fixes files to be usable within mozilla-central tree.
See https://bugzilla.mozilla.org/show_bug.cgi?id=933257

View file

@ -2,7 +2,7 @@
set -e
BASE_URL=https://raw.githubusercontent.com/freebsd/freebsd/master/lib/msun/src
BASE_URL=https://raw.githubusercontent.com/freebsd/freebsd/"${1}"/lib/msun/src
download_source() {
REMOTE_FILENAME=$1
@ -105,7 +105,6 @@ download_source s_scalbn.c s_scalbn.cpp
# These are not not used in Math.* functions, but used internally.
download_source e_pow.c e_pow.cpp
download_source e_sqrt.c e_sqrt.cpp
download_source s_nearbyint.c s_nearbyint.cpp
download_source s_rint.c s_rint.cpp

View file

@ -6,7 +6,7 @@
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/

View file

@ -69,8 +69,8 @@ __ieee754_atan2(double y, double x)
iy = hy&0x7fffffff;
if(((ix|((lx|-lx)>>31))>0x7ff00000)||
((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */
return x+y;
if((hx-0x3ff00000|lx)==0) return atan(y); /* x=1.0 */
return nan_mix(x, y);
if(hx==0x3ff00000&&lx==0) return atan(y); /* x=1.0 */
m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */
/* when y = 0 */

View file

@ -147,9 +147,9 @@ __ieee754_exp(double x) /* default IEEE double exp */
/* x is now in primary range */
t = x*x;
if(k >= -1021)
INSERT_WORDS(twopk,0x3ff00000+(k<<20), 0);
INSERT_WORDS(twopk,((u_int32_t)(0x3ff+k))<<20, 0);
else
INSERT_WORDS(twopk,0x3ff00000+((k+1000)<<20), 0);
INSERT_WORDS(twopk,((u_int32_t)(0x3ff+(k+1000)))<<20, 0);
c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
if(k==0) return one-((x*c)/(c-2.0)-x);
else y = one-((lo-(x*c)/(2.0-c))-hi);

View file

@ -70,7 +70,7 @@ __ieee754_hypot(double x, double y)
if(ha >= 0x7ff00000) { /* Inf or NaN */
u_int32_t low;
/* Use original arg order iff result is NaN; quieten sNaNs. */
w = fabs(x+0.0)-fabs(y+0.0);
w = fabsl(x+0.0L)-fabs(y+0);
GET_LOW_WORD(low,a);
if(((ha&0xfffff)|low)==0) w = a;
GET_LOW_WORD(low,b);

View file

@ -4,7 +4,7 @@
* Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
*
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
@ -19,7 +19,7 @@
* 1. Compute and return log2(x) in two pieces:
* log2(x) = w1 + w2,
* where w1 has 53-24 = 29 bit trailing zeros.
* 2. Perform y*log2(x) = n+y' by simulating multi-precision
* 2. Perform y*log2(x) = n+y' by simulating multi-precision
* arithmetic, where |y'|<=0.5.
* 3. Return x**y = 2**n*exp(y'*log2)
*
@ -47,18 +47,19 @@
* Accuracy:
* pow(x,y) returns x**y nearly rounded. In particular
* pow(integer,integer)
* always returns the correct integer provided it is
* always returns the correct integer provided it is
* representable.
*
* 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
* 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 <cmath>
#include <float.h>
#include "math_private.h"
static const double
@ -66,6 +67,9 @@ bp[] = {1.0, 1.5,},
dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
zero = 0.0,
half = 0.5,
qrtr = 0.25,
thrd = 3.3333333333333331e-01, /* 0x3fd55555, 0x55555555 */
one = 1.0,
two = 2.0,
two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */
@ -108,15 +112,15 @@ __ieee754_pow(double x, double y)
ix = hx&0x7fffffff; iy = hy&0x7fffffff;
/* y==zero: x**0 = 1 */
if((iy|ly)==0) return one;
if((iy|ly)==0) return one;
/* x==1: 1**y = 1, even if y is NaN */
if (hx==0x3ff00000 && lx == 0) return one;
/* y!=zero: result is NaN if either arg is NaN */
if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
return (x+0.0)+(y+0.0);
iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
return nan_mix(x, y);
/* determine if y is an odd int when x < 0
* yisint = 0 ... y is not an integer
@ -124,22 +128,22 @@ __ieee754_pow(double x, double y)
* yisint = 2 ... y is an even int
*/
yisint = 0;
if(hx<0) {
if(hx<0) {
if(iy>=0x43400000) yisint = 2; /* even integer y */
else if(iy>=0x3ff00000) {
k = (iy>>20)-0x3ff; /* exponent */
if(k>20) {
j = ly>>(52-k);
if((j<<(52-k))==ly) yisint = 2-(j&1);
if(((u_int32_t)j<<(52-k))==ly) yisint = 2-(j&1);
} else if(ly==0) {
j = iy>>(20-k);
if((j<<(20-k))==iy) yisint = 2-(j&1);
}
}
}
}
}
/* special value of y */
if(ly==0) {
if(ly==0) {
if (iy==0x7ff00000) { /* y is +-inf */
if(((ix-0x3ff00000)|lx)==0)
return one; /* (-1)**+-inf is 1 */
@ -147,7 +151,7 @@ __ieee754_pow(double x, double y)
return (hy>=0)? y: zero;
else /* (|x|<1)**-,+inf = inf,0 */
return (hy<0)?-y: zero;
}
}
if(iy==0x3ff00000) { /* y is +-1 */
if(hy<0) return one/x; else return x;
}
@ -167,13 +171,13 @@ __ieee754_pow(double x, double y)
if(hx<0) {
if(((ix-0x3ff00000)|yisint)==0) {
z = (z-z)/(z-z); /* (-1)**non-int is NaN */
} else if(yisint==1)
} else if(yisint==1)
z = -z; /* (x<0)**odd = -(|x|**odd) */
}
return z;
}
}
/* CYGNUS LOCAL + fdlibm-5.3 fix: This used to be
n = (hx>>31)+1;
but ANSI C says a right shift of a signed negative quantity is
@ -195,10 +199,10 @@ __ieee754_pow(double x, double y)
/* over/underflow if x is not close to one */
if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny;
if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny;
/* now |1-x| is tiny <= 2**-20, suffice to compute
/* now |1-x| is tiny <= 2**-20, suffice to compute
log(x) by x-x^2/2+x^3/3-x^4/4 */
t = ax-one; /* t has 20 trailing zeros */
w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
w = (t*t)*(half-t*(thrd-t*qrtr));
u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
v = t*ivln2_l-w*ivln2;
t1 = u+v;
@ -235,9 +239,9 @@ __ieee754_pow(double x, double y)
r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
r += s_l*(s_h+ss);
s2 = s_h*s_h;
t_h = 3.0+s2+r;
t_h = 3+s2+r;
SET_LOW_WORD(t_h,0);
t_l = r-((t_h-3.0)-s2);
t_l = r-((t_h-3)-s2);
/* u+v = ss*(1+...) */
u = s_h*t_h;
v = s_l*t_h+t_l*ss;
@ -248,7 +252,7 @@ __ieee754_pow(double x, double y)
z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
z_l = cp_l*p_h+p_l*cp+dp_l[k];
/* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
t = (double)n;
t = n;
t1 = (((z_h+z_l)+dp_h[k])+t);
SET_LOW_WORD(t1,0);
t2 = z_l-(((t1-t)-dp_h[k])-z_h);
@ -288,7 +292,7 @@ __ieee754_pow(double x, double y)
n = ((n&0x000fffff)|0x00100000)>>(20-k);
if(j<0) n = -n;
p_h -= t;
}
}
t = p_l+p_h;
SET_LOW_WORD(t,0);
u = t*lg2_h;

View file

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*

View file

@ -45,6 +45,47 @@
#define u_int64_t uint64_t
#endif
/* A union which permits us to convert between a long double and
four 32 bit ints. */
#if MOZ_BIG_ENDIAN
typedef union
{
long double value;
struct {
u_int32_t mswhi;
u_int32_t mswlo;
u_int32_t lswhi;
u_int32_t lswlo;
} parts32;
struct {
u_int64_t msw;
u_int64_t lsw;
} parts64;
} ieee_quad_shape_type;
#endif
#if MOZ_LITTLE_ENDIAN
typedef union
{
long double value;
struct {
u_int32_t lswlo;
u_int32_t lswhi;
u_int32_t mswlo;
u_int32_t mswhi;
} parts32;
struct {
u_int64_t lsw;
u_int64_t msw;
} parts64;
} ieee_quad_shape_type;
#endif
/*
* A union which permits us to convert between a double and two 32 bit
* ints.
@ -307,8 +348,9 @@ do { \
/* Support switching the mode to FP_PE if necessary. */
#if defined(__i386__) && !defined(NO_FPSETPREC)
#define ENTERI() \
long double __retval; \
#define ENTERI() ENTERIT(long double)
#define ENTERIT(returntype) \
returntype __retval; \
fp_prec_t __oprec; \
\
if ((__oprec = fpgetprec()) != FP_PE) \
@ -319,9 +361,22 @@ do { \
fpsetprec(__oprec); \
RETURNF(__retval); \
} while (0)
#define ENTERV() \
fp_prec_t __oprec; \
\
if ((__oprec = fpgetprec()) != FP_PE) \
fpsetprec(FP_PE)
#define RETURNV() do { \
if (__oprec != FP_PE) \
fpsetprec(__oprec); \
return; \
} while (0)
#else
#define ENTERI(x)
#define ENTERI()
#define ENTERIT(x)
#define RETURNI(x) RETURNF(x)
#define ENTERV()
#define RETURNV() return
#endif
/* Default return statement if hack*_t() is not used. */
@ -436,6 +491,31 @@ do { \
*/
void _scan_nan(uint32_t *__words, int __num_words, const char *__s);
/*
* Mix 0, 1 or 2 NaNs. First add 0 to each arg. This normally just turns
* signaling NaNs into quiet NaNs by setting a quiet bit. We do this
* because we want to never return a signaling NaN, and also because we
* don't want the quiet bit to affect the result. Then mix the converted
* args using the specified operation.
*
* When one arg is NaN, the result is typically that arg quieted. When both
* args are NaNs, the result is typically the quietening of the arg whose
* mantissa is largest after quietening. When neither arg is NaN, the
* result may be NaN because it is indeterminate, or finite for subsequent
* construction of a NaN as the indeterminate 0.0L/0.0L.
*
* Technical complications: the result in bits after rounding to the final
* precision might depend on the runtime precision and/or on compiler
* optimizations, especially when different register sets are used for
* different precisions. Try to make the result not depend on at least the
* runtime precision by always doing the main mixing step in long double
* precision. Try to reduce dependencies on optimizations by adding the
* the 0's in different precisions (unless everything is in long double
* precision).
*/
#define nan_mix(x, y) (nan_mix_op((x), (y), +))
#define nan_mix_op(x, y, op) (((x) + 0.0L) op ((y) + 0))
#ifdef _COMPLEX_H
/*
@ -511,48 +591,6 @@ CMPLXL(long double x, long double y)
#endif /* _COMPLEX_H */
#ifdef __GNUCLIKE_ASM
/* Asm versions of some functions. */
#ifdef __amd64__
static __inline int
irint(double x)
{
int n;
asm("cvtsd2si %1,%0" : "=r" (n) : "x" (x));
return (n);
}
#define HAVE_EFFICIENT_IRINT
#endif
#ifdef __i386__
static __inline int
irint(double x)
{
int n;
asm("fistl %0" : "=m" (n) : "t" (x));
return (n);
}
#define HAVE_EFFICIENT_IRINT
#endif
#if defined(__amd64__) || defined(__i386__)
static __inline int
irintl(long double x)
{
int n;
asm("fistl %0" : "=m" (n) : "t" (x));
return (n);
}
#define HAVE_EFFICIENT_IRINTL
#endif
#endif /* __GNUCLIKE_ASM */
#ifdef DEBUG
#if defined(__amd64__) || defined(__i386__)
#define breakpoint() asm("int $3")

View file

@ -10,26 +10,35 @@ EXPORTS += [
FINAL_LIBRARY = 'js'
if CONFIG['GNU_CXX']:
if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
CXXFLAGS += [
'-Wno-parentheses',
'-Wno-sign-compare',
]
if CONFIG['CLANG_CXX']:
if CONFIG['CC_TYPE'] == 'clang':
CXXFLAGS += [
'-Wno-dangling-else',
]
if CONFIG['_MSC_VER']:
if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
CXXFLAGS += [
'-wd4018', # signed/unsigned mismatch
'-wd4146', # unary minus operator applied to unsigned type
'-wd4305', # truncation from 'double' to 'const float'
'-wd4723', # potential divide by 0
'-wd4756', # overflow in constant arithmetic
]
if CONFIG['CC_TYPE'] == 'msvc':
CXXFLAGS += [
'-wd4018', # signed/unsigned mismatch
]
if CONFIG['CC_TYPE'] == 'clang-cl':
CXXFLAGS += [
'-Wno-sign-compare', # signed/unsigned mismatch
]
SOURCES += [
'e_acos.cpp',
'e_acosh.cpp',

View file

@ -15,6 +15,7 @@
//#include <sys/cdefs.h>
//__FBSDID("$FreeBSD$");
#include <float.h>
#include "math_private.h"
/* cbrt(x)

View file

@ -187,7 +187,7 @@ expm1(double x)
e = hxs*((r1-t)/(6.0 - x*t));
if(k==0) return x - (x*e-hxs); /* c is 0 */
else {
INSERT_WORDS(twopk,0x3ff00000+(k<<20),0); /* 2^k */
INSERT_WORDS(twopk,((u_int32_t)(0x3ff+k))<<20,0); /* 2^k */
e = (x*(e-c)-c);
e -= hxs;
if(k== -1) return 0.5*(x-e)-0.5;

View file

@ -1,4 +1,4 @@
/* @(#)s_fabs.c 5.1 93/09/24 */
/* @(#)s_fabs.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@ -10,9 +10,8 @@
* ====================================================
*/
#ifndef lint
//static char rcsid[] = "$FreeBSD$";
#endif
//#include <sys/cdefs.h>
//__FBSDID("$FreeBSD$");
/*
* fabs(x) returns the absolute value of x.

View file

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*

View file

@ -10,9 +10,8 @@
* ====================================================
*/
#ifndef lint
//static char rcsid[] = "$FreeBSD$";
#endif
//#include <sys/cdefs.h>
//__FBSDID("$FreeBSD$");
/*
* scalbn (double x, int n)
@ -21,7 +20,6 @@
* exponentiation or a multiplication.
*/
//#include <sys/cdefs.h>
#include <float.h>
#include "math_private.h"
@ -50,10 +48,12 @@ scalbn (double x, int n)
if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */
if (k > 0) /* normal result */
{SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
if (k <= -54)
if (k <= -54) {
if (n > 50000) /* in case integer overflow in n+k */
return huge*copysign(huge,x); /*overflow*/
else return tiny*copysign(tiny,x); /*underflow*/
else
return tiny*copysign(tiny,x); /*underflow*/
}
k += 54; /* subnormal result */
SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
return x*twom54;

View file

@ -11,23 +11,28 @@ get_commit() {
curl -s "${API_BASE_URL}/commits?path=lib/msun/src&per_page=1" \
| python -c 'import json, sys; print(json.loads(sys.stdin.read())[0]["sha"])'
}
get_date() {
curl -s "${API_BASE_URL}/commits/${COMMIT}" \
| python -c 'import json, sys; print(json.loads(sys.stdin.read())["commit"]["committer"]["date"])'
}
mv ./src/moz.build ./src_moz.build
rm -rf src
BEFORE_COMMIT=$(get_commit)
sh ./import.sh
mv ./src_moz.build ./src/moz.build
COMMIT=$(get_commit)
if [ ${BEFORE_COMMIT} != ${COMMIT} ]; then
echo "Latest commit is changed during import. Please run again."
exit 1
if [ "$#" -eq 0 ]; then
COMMIT=$(get_commit)
else
COMMIT="$1"
fi
sh ./import.sh "${COMMIT}"
mv ./src_moz.build ./src/moz.build
COMMITDATE=$(get_date)
for FILE in $(ls patches/*.patch | sort); do
patch -p3 < ${FILE}
echo "Applying ${FILE} ..."
patch -p3 --no-backup-if-mismatch < ${FILE}
done
hg add src
perl -p -i -e "s/\[commit [0-9a-f]{40}\]/[commit ${COMMIT}]/" README.mozilla
perl -p -i -e "s/\[commit [0-9a-f]{40} \(.{1,100}\)\]/[commit ${COMMIT} (${COMMITDATE})]/" README.mozilla
echo "###"
echo "### Updated fdlibm/src to ${COMMIT}."