diff --git a/BUILD.gn b/BUILD.gn index 0e09b63f5d..11ed823a12 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1063,6 +1063,9 @@ config("features") { if (v8_use_zlib) { defines += [ "V8_USE_ZLIB" ] } + if (v8_use_libm_trig_functions) { + defines += [ "V8_USE_LIBM_TRIG_FUNCTIONS" ] + } if (v8_value_deserializer_hard_fail) { defines += [ "V8_VALUE_DESERIALIZER_HARD_FAIL" ] } @@ -5676,9 +5679,37 @@ v8_component("v8_libbase") { [ "//build/config/clang:llvm-symbolizer_data($host_toolchain)" ] } + if (v8_use_libm_trig_functions) { + deps += [ ":libm" ] + } + # TODO(infra): Add support for qnx, freebsd, openbsd, netbsd, and solaris. } +if (v8_use_libm_trig_functions) { + source_set("libm") { + sources = [ + "third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.c", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.h", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/dla.h", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/endian.h", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/mydefs.h", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/sincostab.c", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/s_sin.c", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/usncs.h", + ] + configs += [ + "//build/config/compiler:no_chromium_code", + ] + configs -= [ "//build/config/compiler:chromium_code" ] + if (!is_debug) { + # Build code using -O3, see: crbug.com/1084371. + configs += [ "//build/config/compiler:optimize_speed" ] + } + } +} + v8_component("v8_libplatform") { sources = [ "//base/trace_event/common/trace_event_common.h", diff --git a/gni/v8.gni b/gni/v8.gni index 3f093597fa..f297eb379b 100644 --- a/gni/v8.gni +++ b/gni/v8.gni @@ -107,6 +107,9 @@ declare_args() { # Enable advanced BigInt algorithms, costing about 10-30 KB binary size # depending on platform. Disabled on Android to save binary size. v8_advanced_bigint_algorithms = !is_android + + # TODO: macros for determining endian type are clang specific. + v8_use_libm_trig_functions = is_clang } if (v8_use_external_startup_data == "") { diff --git a/src/base/DEPS b/src/base/DEPS index a9c31c20d6..3cead70516 100644 --- a/src/base/DEPS +++ b/src/base/DEPS @@ -5,3 +5,9 @@ include_rules = [ "-src", "+src/base", ] + +specific_include_rules = { + "ieee754.h": [ + "+third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h" + ], +} diff --git a/src/base/ieee754.cc b/src/base/ieee754.cc index 73672001cf..f03044611a 100644 --- a/src/base/ieee754.cc +++ b/src/base/ieee754.cc @@ -105,10 +105,12 @@ namespace { } while (false) int32_t __ieee754_rem_pio2(double x, double* y) V8_WARN_UNUSED_RESULT; -double __kernel_cos(double x, double y) V8_WARN_UNUSED_RESULT; int __kernel_rem_pio2(double* x, double* y, int e0, int nx, int prec, const int32_t* ipio2) V8_WARN_UNUSED_RESULT; +#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS) +double __kernel_cos(double x, double y) V8_WARN_UNUSED_RESULT; double __kernel_sin(double x, double y, int iy) V8_WARN_UNUSED_RESULT; +#endif /* __ieee754_rem_pio2(x,y) * @@ -269,6 +271,7 @@ int32_t __ieee754_rem_pio2(double x, double *y) { return n; } +#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS) /* __kernel_cos( x, y ) * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 * Input x is assumed to be bounded by ~pi/4 in magnitude. @@ -334,6 +337,7 @@ V8_INLINE double __kernel_cos(double x, double y) { return a - (iz - (z * r - x * y)); } } +#endif /* __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) * double x[],y[]; int e0,nx,prec; int ipio2[]; @@ -643,6 +647,7 @@ recompute: return n & 7; } +#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS) /* __kernel_sin( x, y, iy) * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854 * Input x is assumed to be bounded by ~pi/4 in magnitude. @@ -696,6 +701,7 @@ V8_INLINE double __kernel_sin(double x, double y, int iy) { return x - ((z * (half * y - v * r) - y) - v * S1); } } +#endif /* __kernel_tan( x, y, k ) * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854 @@ -1318,6 +1324,7 @@ double atan2(double y, double x) { } } +#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS) /* cos(x) * Return cosine function of x. * @@ -1377,6 +1384,7 @@ double cos(double x) { } } } +#endif /* exp(x) * Returns the exponential of x. @@ -2410,6 +2418,7 @@ double cbrt(double x) { return (t); } +#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS) /* sin(x) * Return sine function of x. * @@ -2469,6 +2478,7 @@ double sin(double x) { } } } +#endif /* tan(x) * Return tangent function of x. @@ -3015,6 +3025,15 @@ double tanh(double x) { #undef SET_HIGH_WORD #undef SET_LOW_WORD +#if defined(V8_USE_LIBM_TRIG_FUNCTIONS) && defined(BUILDING_V8_BASE_SHARED) +double sin(double x) { + return glibc_sin(x); +} +double cos(double x) { + return glibc_cos(x); +} +#endif + } // namespace ieee754 } // namespace base } // namespace v8 diff --git a/src/base/ieee754.h b/src/base/ieee754.h index f2b3a3eb58..53417179e6 100644 --- a/src/base/ieee754.h +++ b/src/base/ieee754.h @@ -7,6 +7,10 @@ #include "src/base/base-export.h" +#if defined(V8_USE_LIBM_TRIG_FUNCTIONS) +#include "third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h" // nogncheck +#endif + namespace v8 { namespace base { namespace ieee754 { @@ -34,7 +38,15 @@ V8_BASE_EXPORT double atan(double x); V8_BASE_EXPORT double atan2(double y, double x); // Returns the cosine of |x|, where |x| is given in radians. +#if defined(V8_USE_LIBM_TRIG_FUNCTIONS) && \ + !defined(BUILDING_V8_BASE_SHARED) && \ + !defined(USING_V8_BASE_SHARED) +inline double cos(double x) { + return glibc_cos(x); +} +#else V8_BASE_EXPORT double cos(double x); +#endif // Returns the base-e exponential of |x|. V8_BASE_EXPORT double exp(double x); @@ -68,8 +80,16 @@ V8_BASE_EXPORT double expm1(double x); // behaviour is preserved for compatibility reasons. V8_BASE_EXPORT double pow(double x, double y); +#if defined(V8_USE_LIBM_TRIG_FUNCTIONS) && \ + !defined(BUILDING_V8_BASE_SHARED) && \ + !defined(USING_V8_BASE_SHARED) +inline double sin(double x) { + return glibc_sin(x); +} +#else // Returns the sine of |x|, where |x| is given in radians. V8_BASE_EXPORT double sin(double x); +#endif // Returns the tangent of |x|, where |x| is given in radians. V8_BASE_EXPORT double tan(double x); diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.c b/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.c index 8af4890d9a..3abfa1e0b4 100644 --- a/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.c +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.c @@ -34,8 +34,8 @@ #include "endian.h" #include "mydefs.h" #include "branred.h" + #include -#include #ifndef SECTION # define SECTION diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.h b/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.h index 1107f9becb..d113c8530d 100644 --- a/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.h +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.h @@ -25,7 +25,7 @@ #ifndef BRANRED_H #define BRANRED_H -#include +#include "dla.h" #ifdef BIG_ENDI static const mynumber diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/dla.h b/third_party/glibc/src/sysdeps/ieee754/dbl-64/dla.h index d6630e309b..db4c4d81de 100644 --- a/third_party/glibc/src/sysdeps/ieee754/dbl-64/dla.h +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/dla.h @@ -16,8 +16,6 @@ * along with this program; if not, see . */ -#include - /***********************************************************************/ /*MODULE_NAME: dla.h */ /* */ @@ -38,149 +36,3 @@ /* 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) \ - z = x * y; zz = DLA_FMS (x, y, z); -#else -# define EMULV(x, y, z, zz) \ - ({ __typeof__ (x) __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) \ - EMULV(x, y, z, zz) -#else -# define MUL12(x, y, z, zz) \ - ({ __typeof__ (x) __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, c, cc) \ - MUL12 (x, y, c, cc); \ - 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, c, cc, u, uu) \ - c=(x)/(y); MUL12(c,y,u,uu); \ - 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); } diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/endian.h b/third_party/glibc/src/sysdeps/ieee754/dbl-64/endian.h new file mode 100644 index 0000000000..d97daca4df --- /dev/null +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/endian.h @@ -0,0 +1,21 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// glibc has a couple of endian.h files. This defines the macros expected by +// the code in this directory using macros defined by clang. +#if (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define BIG_ENDI 1 +#undef LITTLE_ENDI +#define HIGH_HALF 0 +#define LOW_HALF 1 +#elif (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#undef BIG_ENDI +#define LITTLE_ENDI 1 +#define HIGH_HALF 1 +#define LOW_HALF 0 +#else +#error +#endif diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/s_sin.c b/third_party/glibc/src/sysdeps/ieee754/dbl-64/s_sin.c index 8e65f7cc00..a7beb04f97 100644 --- a/third_party/glibc/src/sysdeps/ieee754/dbl-64/s_sin.c +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/s_sin.c @@ -39,11 +39,11 @@ #include "mydefs.h" #include "usncs.h" #include -#include -#include -#include -#include -#include + +#define attribute_hidden +#if !defined(__always_inline) +#define __always_inline +#endif /* Helper macros to compute sin of the input values. */ #define POLYNOMIAL2(xx) ((((s5 * (xx) + s4) * (xx) + s3) * (xx) + s2) * (xx)) @@ -197,21 +197,18 @@ do_sincos (double a, double da, int4 n) #ifndef IN_SINCOS double SECTION -__sin (double x) +glibc_sin (double x) { double t, a, da; mynumber u; int4 k, m, n; double retval = 0; - SET_RESTORE_ROUND_53BIT (FE_TONEAREST); - u.x = x; m = u.i[HIGH_HALF]; k = 0x7fffffff & m; /* no sign */ if (k < 0x3e500000) /* if x->0 =>sin(x)=x */ { - math_check_force_underflow (x); retval = x; } /*--------------------------- 2^-26<|x|< 0.855469---------------------- */ @@ -245,8 +242,6 @@ __sin (double x) /*--------------------- |x| > 2^1024 ----------------------------------*/ else { - if (k == 0x7ff00000 && u.i[LOW_HALF] == 0) - __set_errno (EDOM); retval = x / x; } @@ -261,7 +256,7 @@ __sin (double x) double SECTION -__cos (double x) +glibc_cos (double x) { double y, a, da; mynumber u; @@ -269,8 +264,6 @@ __cos (double x) double retval = 0; - SET_RESTORE_ROUND_53BIT (FE_TONEAREST); - u.x = x; m = u.i[HIGH_HALF]; k = 0x7fffffff & m; @@ -310,19 +303,10 @@ __cos (double x) else { - if (k == 0x7ff00000 && u.i[LOW_HALF] == 0) - __set_errno (EDOM); retval = x / x; /* |x| > 2^1024 */ } return retval; } -#ifndef __cos -libm_alias_double (__cos, cos) -#endif -#ifndef __sin -libm_alias_double (__sin, sin) -#endif - #endif diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/sincostab.c b/third_party/glibc/src/sysdeps/ieee754/dbl-64/sincostab.c index d88e55c6de..8ae29e2f02 100644 --- a/third_party/glibc/src/sysdeps/ieee754/dbl-64/sincostab.c +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/sincostab.c @@ -16,8 +16,8 @@ * along with this program; if not, see . */ -#include -#include +#include "mydefs.h" +#include "endian.h" /****************************************************************/ /* TABLES FOR THE usin() and ucos() FUNCTION */ diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h b/third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h new file mode 100644 index 0000000000..e4dac73048 --- /dev/null +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h @@ -0,0 +1,14 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifdef __cplusplus +extern "C" { +#endif + +double glibc_cos(double x); +double glibc_sin(double x); + +#ifdef __cplusplus +} // extern "C" +#endif