Bug 1303085: Add nearbyint/nearbyintf to fdlibm; r=arai
authorBenjamin Bouvier <benj@benj.me>
Thu, 15 Sep 2016 20:57:47 +0200
changeset 357484 420aea33cee63aed1f69ea80b5876a4b5338ccc3
parent 357483 9104d282eb5606fb2d35e671386c02bb19348dd9
child 357485 922941564e6a07117bd3d607f509de2dc57eab76
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1303085
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1303085: Add nearbyint/nearbyintf to fdlibm; r=arai MozReview-Commit-ID: GahbeGVPKs
js/src/asmjs/WasmTypes.cpp
modules/fdlibm/README.mozilla
modules/fdlibm/import.sh
modules/fdlibm/src/fdlibm.h
modules/fdlibm/src/math_private.h
modules/fdlibm/src/moz.build
modules/fdlibm/src/s_nearbyint.cpp
modules/fdlibm/src/s_rint.cpp
modules/fdlibm/src/s_rintf.cpp
--- a/js/src/asmjs/WasmTypes.cpp
+++ b/js/src/asmjs/WasmTypes.cpp
@@ -338,19 +338,19 @@ wasm::AddressOf(SymbolicAddress imm, Exc
         return FuncCast<double (double)>(fdlibm::floor, Args_Double_Double);
       case SymbolicAddress::FloorF:
         return FuncCast<float (float)>(fdlibm::floorf, Args_Float32_Float32);
       case SymbolicAddress::TruncD:
         return FuncCast<double (double)>(fdlibm::trunc, Args_Double_Double);
       case SymbolicAddress::TruncF:
         return FuncCast<float (float)>(fdlibm::truncf, Args_Float32_Float32);
       case SymbolicAddress::NearbyIntD:
-        return FuncCast<double (double)>(nearbyint, Args_Double_Double);
+        return FuncCast<double (double)>(fdlibm::nearbyint, Args_Double_Double);
       case SymbolicAddress::NearbyIntF:
-        return FuncCast<float (float)>(nearbyintf, Args_Float32_Float32);
+        return FuncCast<float (float)>(fdlibm::nearbyintf, Args_Float32_Float32);
       case SymbolicAddress::ExpD:
         return FuncCast<double (double)>(fdlibm::exp, Args_Double_Double);
       case SymbolicAddress::LogD:
         return FuncCast<double (double)>(fdlibm::log, Args_Double_Double);
       case SymbolicAddress::PowD:
         return FuncCast(ecmaPow, Args_Double_DoubleDouble);
       case SymbolicAddress::ATan2D:
         return FuncCast(ecmaAtan2, Args_Double_DoubleDouble);
--- a/modules/fdlibm/README.mozilla
+++ b/modules/fdlibm/README.mozilla
@@ -6,12 +6,12 @@ Upstream code can be viewed at
 
 Each file is downloaded separately, as cloning whole repository takes so much
 resources.
 
 The in-tree copy is updated by running
   sh update.sh
 from within the modules/fdlibm directory.
 
-Current version: [commit 9e7434b2c5c2ce4f2a9aa3e84de3e7cf33a910d5].
+Current version: [commit f2287da07ac7a26ac08745cac66eec82ab9ba384].
 
 patches 01-14 fixes files to be usable within mozilla-central tree.
 See https://bugzilla.mozilla.org/show_bug.cgi?id=933257
--- a/modules/fdlibm/import.sh
+++ b/modules/fdlibm/import.sh
@@ -101,8 +101,12 @@ download_source s_truncf.c s_truncf.cpp
 download_source k_exp.c k_exp.cpp
 download_source s_copysign.c s_copysign.cpp
 download_source s_fabs.c s_fabs.cpp
 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
+download_source s_rintf.c s_rintf.cpp
--- a/modules/fdlibm/src/fdlibm.h
+++ b/modules/fdlibm/src/fdlibm.h
@@ -43,19 +43,23 @@ double	ceil(double);
 double	acosh(double);
 double	asinh(double);
 double	atanh(double);
 double	cbrt(double);
 double	expm1(double);
 double	hypot(double, double);
 double	log1p(double);
 double	log2(double);
-
+double	rint(double);
 double	copysign(double, double);
+double	nearbyint(double);
 double	scalbn(double, int);
 
+float	ceilf(float);
 float	floorf(float);
+
+float	nearbyintf(float);
+float	rintf(float);
 float	truncf(float);
-float	ceilf(float);
 
 } /* namespace fdlibm */
 
 #endif /* mozilla_imported_fdlibm_h */
--- a/modules/fdlibm/src/math_private.h
+++ b/modules/fdlibm/src/math_private.h
@@ -771,16 +771,20 @@ irintl(long double x)
 #define log1p fdlibm::log1p
 #define log2 fdlibm::log2
 #define scalb fdlibm::scalb
 #define copysign fdlibm::copysign
 #define scalbn fdlibm::scalbn
 #define trunc fdlibm::trunc
 #define truncf fdlibm::truncf
 #define floorf fdlibm::floorf
+#define nearbyint fdlibm::nearbyint
+#define nearbyintf fdlibm::nearbyintf
+#define rint fdlibm::rint
+#define rintf fdlibm::rintf
 
 /* fdlibm kernel function */
 int	__kernel_rem_pio2(double*,double*,int,int,int);
 
 /* double precision kernel functions */
 #ifndef INLINE_REM_PIO2
 int	__ieee754_rem_pio2(double,double*);
 #endif
--- a/modules/fdlibm/src/moz.build
+++ b/modules/fdlibm/src/moz.build
@@ -52,13 +52,16 @@ SOURCES += [
     's_ceil.cpp',
     's_ceilf.cpp',
     's_copysign.cpp',
     's_expm1.cpp',
     's_fabs.cpp',
     's_floor.cpp',
     's_floorf.cpp',
     's_log1p.cpp',
+    's_nearbyint.cpp',
+    's_rint.cpp',
+    's_rintf.cpp',
     's_scalbn.cpp',
     's_tanh.cpp',
     's_trunc.cpp',
     's_truncf.cpp',
 ]
new file mode 100644
--- /dev/null
+++ b/modules/fdlibm/src/s_nearbyint.cpp
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+//#include <sys/cdefs.h>
+//__FBSDID("$FreeBSD$");
+
+#include <fenv.h>
+#include "math_private.h"
+
+/*
+ * We save and restore the floating-point environment to avoid raising
+ * an inexact exception.  We can get away with using fesetenv()
+ * instead of feclearexcept()/feupdateenv() to restore the environment
+ * because the only exception defined for rint() is overflow, and
+ * rounding can't overflow as long as emax >= p.
+ *
+ * The volatile keyword is needed below because clang incorrectly assumes
+ * that rint won't raise any floating-point exceptions. Declaring ret volatile
+ * is sufficient to trick the compiler into doing the right thing.
+ */
+#define	DECL(type, fn, rint)	\
+type				\
+fn(type x)			\
+{				\
+	volatile type ret;	\
+	fenv_t env;		\
+				\
+	fegetenv(&env);		\
+	ret = rint(x);		\
+	fesetenv(&env);		\
+	return (ret);		\
+}
+
+DECL(double, nearbyint, rint)
+DECL(float, nearbyintf, rintf)
new file mode 100644
--- /dev/null
+++ b/modules/fdlibm/src/s_rint.cpp
@@ -0,0 +1,87 @@
+/* @(#)s_rint.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+//#include <sys/cdefs.h>
+//__FBSDID("$FreeBSD$");
+
+/*
+ * rint(x)
+ * Return x rounded to integral value according to the prevailing
+ * rounding mode.
+ * Method:
+ *	Using floating addition.
+ * Exception:
+ *	Inexact flag raised if x not equal to rint(x).
+ */
+
+#include <float.h>
+
+#include "math_private.h"
+
+static const double
+TWO52[2]={
+  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+};
+
+double
+rint(double x)
+{
+	int32_t i0,j0,sx;
+	u_int32_t i,i1;
+	double w,t;
+	EXTRACT_WORDS(i0,i1,x);
+	sx = (i0>>31)&1;
+	j0 = ((i0>>20)&0x7ff)-0x3ff;
+	if(j0<20) {
+	    if(j0<0) {
+		if(((i0&0x7fffffff)|i1)==0) return x;
+		i1 |= (i0&0x0fffff);
+		i0 &= 0xfffe0000;
+		i0 |= ((i1|-i1)>>12)&0x80000;
+		SET_HIGH_WORD(x,i0);
+	        STRICT_ASSIGN(double,w,TWO52[sx]+x);
+	        t =  w-TWO52[sx];
+		GET_HIGH_WORD(i0,t);
+		SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
+	        return t;
+	    } else {
+		i = (0x000fffff)>>j0;
+		if(((i0&i)|i1)==0) return x; /* x is integral */
+		i>>=1;
+		if(((i0&i)|i1)!=0) {
+		    /*
+		     * Some bit is set after the 0.5 bit.  To avoid the
+		     * possibility of errors from double rounding in
+		     * w = TWO52[sx]+x, adjust the 0.25 bit to a lower
+		     * guard bit.  We do this for all j0<=51.  The
+		     * adjustment is trickiest for j0==18 and j0==19
+		     * since then it spans the word boundary.
+		     */
+		    if(j0==19) i1 = 0x40000000; else
+		    if(j0==18) i1 = 0x80000000; else
+		    i0 = (i0&(~i))|((0x20000)>>j0);
+		}
+	    }
+	} else if (j0>51) {
+	    if(j0==0x400) return x+x;	/* inf or NaN */
+	    else return x;		/* x is integral */
+	} else {
+	    i = ((u_int32_t)(0xffffffff))>>(j0-20);
+	    if((i1&i)==0) return x;	/* x is integral */
+	    i>>=1;
+	    if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
+	}
+	INSERT_WORDS(x,i0,i1);
+	STRICT_ASSIGN(double,w,TWO52[sx]+x);
+	return w-TWO52[sx];
+}
new file mode 100644
--- /dev/null
+++ b/modules/fdlibm/src/s_rintf.cpp
@@ -0,0 +1,52 @@
+/* s_rintf.c -- float version of s_rint.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 <sys/cdefs.h>
+//__FBSDID("$FreeBSD$");
+
+#include <float.h>
+#include <stdint.h>
+
+#include "math_private.h"
+
+static const float
+TWO23[2]={
+  8.3886080000e+06, /* 0x4b000000 */
+ -8.3886080000e+06, /* 0xcb000000 */
+};
+
+float
+rintf(float x)
+{
+	int32_t i0,j0,sx;
+	float w,t;
+	GET_FLOAT_WORD(i0,x);
+	sx = (i0>>31)&1;
+	j0 = ((i0>>23)&0xff)-0x7f;
+	if(j0<23) {
+	    if(j0<0) {
+		if((i0&0x7fffffff)==0) return x;
+		STRICT_ASSIGN(float,w,TWO23[sx]+x);
+	        t =  w-TWO23[sx];
+		GET_FLOAT_WORD(i0,t);
+		SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
+	        return t;
+	    }
+	    STRICT_ASSIGN(float,w,TWO23[sx]+x);
+	    return w-TWO23[sx];
+	}
+	if(j0==0x80) return x+x;	/* inf or NaN */
+	else return x;			/* x is integral */
+}