From 38920d4ca62266e841c6a7179e4243942c1957e5 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Thu, 15 Sep 2016 20:57:47 +0200 Subject: [PATCH] Bug 1303085: Add nearbyint/nearbyintf to fdlibm; r=arai MozReview-Commit-ID: GahbeGVPKs --HG-- extra : rebase_source : 521205f9c6fe5d559efa2d0c854f906857c10f36 extra : histedit_source : bd0bf1fb258fc6aac8a33b18f529a43f0130ff68 --- js/src/asmjs/WasmTypes.cpp | 4 +- modules/fdlibm/README.mozilla | 2 +- modules/fdlibm/import.sh | 4 ++ modules/fdlibm/src/fdlibm.h | 10 ++-- modules/fdlibm/src/math_private.h | 4 ++ modules/fdlibm/src/moz.build | 3 ++ modules/fdlibm/src/s_nearbyint.cpp | 58 ++++++++++++++++++++ modules/fdlibm/src/s_rint.cpp | 87 ++++++++++++++++++++++++++++++ modules/fdlibm/src/s_rintf.cpp | 52 ++++++++++++++++++ 9 files changed, 218 insertions(+), 6 deletions(-) create mode 100644 modules/fdlibm/src/s_nearbyint.cpp create mode 100644 modules/fdlibm/src/s_rint.cpp create mode 100644 modules/fdlibm/src/s_rintf.cpp diff --git a/js/src/asmjs/WasmTypes.cpp b/js/src/asmjs/WasmTypes.cpp index c478ac1cff4a..329a45d2b799 100644 --- a/js/src/asmjs/WasmTypes.cpp +++ b/js/src/asmjs/WasmTypes.cpp @@ -343,9 +343,9 @@ wasm::AddressOf(SymbolicAddress imm, ExclusiveContext* cx) case SymbolicAddress::TruncF: return FuncCast(fdlibm::truncf, Args_Float32_Float32); case SymbolicAddress::NearbyIntD: - return FuncCast(nearbyint, Args_Double_Double); + return FuncCast(fdlibm::nearbyint, Args_Double_Double); case SymbolicAddress::NearbyIntF: - return FuncCast(nearbyintf, Args_Float32_Float32); + return FuncCast(fdlibm::nearbyintf, Args_Float32_Float32); case SymbolicAddress::ExpD: return FuncCast(fdlibm::exp, Args_Double_Double); case SymbolicAddress::LogD: diff --git a/modules/fdlibm/README.mozilla b/modules/fdlibm/README.mozilla index 9b4afdbf9985..3c244961285a 100644 --- a/modules/fdlibm/README.mozilla +++ b/modules/fdlibm/README.mozilla @@ -11,7 +11,7 @@ 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 diff --git a/modules/fdlibm/import.sh b/modules/fdlibm/import.sh index 5a200868e062..67ab1b463fd1 100644 --- a/modules/fdlibm/import.sh +++ b/modules/fdlibm/import.sh @@ -106,3 +106,7 @@ 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 diff --git a/modules/fdlibm/src/fdlibm.h b/modules/fdlibm/src/fdlibm.h index 623cd25b1ab7..0ad2159113cd 100644 --- a/modules/fdlibm/src/fdlibm.h +++ b/modules/fdlibm/src/fdlibm.h @@ -48,13 +48,17 @@ 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 floorf(float); -float truncf(float); float ceilf(float); +float floorf(float); + +float nearbyintf(float); +float rintf(float); +float truncf(float); } /* namespace fdlibm */ diff --git a/modules/fdlibm/src/math_private.h b/modules/fdlibm/src/math_private.h index b9e59446dafb..6947cecc0970 100644 --- a/modules/fdlibm/src/math_private.h +++ b/modules/fdlibm/src/math_private.h @@ -776,6 +776,10 @@ irintl(long double x) #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); diff --git a/modules/fdlibm/src/moz.build b/modules/fdlibm/src/moz.build index 3090dae323d5..6c964532ec2e 100644 --- a/modules/fdlibm/src/moz.build +++ b/modules/fdlibm/src/moz.build @@ -57,6 +57,9 @@ SOURCES += [ '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', diff --git a/modules/fdlibm/src/s_nearbyint.cpp b/modules/fdlibm/src/s_nearbyint.cpp new file mode 100644 index 000000000000..532bb5d8df55 --- /dev/null +++ b/modules/fdlibm/src/s_nearbyint.cpp @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2004 David Schultz + * 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 +//__FBSDID("$FreeBSD$"); + +#include +#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) diff --git a/modules/fdlibm/src/s_rint.cpp b/modules/fdlibm/src/s_rint.cpp new file mode 100644 index 000000000000..19171f87f9c9 --- /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 +//__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 + +#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]; +} diff --git a/modules/fdlibm/src/s_rintf.cpp b/modules/fdlibm/src/s_rintf.cpp new file mode 100644 index 000000000000..3a729b005d52 --- /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 +//__FBSDID("$FreeBSD$"); + +#include +#include + +#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 */ +}