[reland] adds the ability for v8 to use sin/cos from libm

This differs from the patch that landed in so far as the libm target
is only defined if v8_use_libm_trig_functions is defined. Doing this
ensures building the 'all' target only builds libm is appropriate.
You can diff between patchset 1 and 2 to see the change.

This is controlled by a gn arg, which defaults to true for clang
builds. I'm limiting to clang builds as the macros for determining
endian type are currently clang specific. My understanding is that
chrome only uses clang. I can update the endian macros if necessary
for other targets.

Bug=v8:13477

Change-Id: I59cd450facc9fcb8987fe56e8cfc1c13522e1f6d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4070924
Commit-Queue: Hannes Payer <hpayer@chromium.org>
Auto-Submit: Scott Violet <sky@chromium.org>
Reviewed-by: Hannes Payer <hpayer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84620}
This commit is contained in:
Scott Violet 2022-12-01 09:02:12 -08:00 committed by V8 LUCI CQ
parent 74cc4e7d80
commit 7519793938
12 changed files with 126 additions and 176 deletions

View File

@ -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",

View File

@ -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 == "") {

View File

@ -5,3 +5,9 @@ include_rules = [
"-src",
"+src/base",
]
specific_include_rules = {
"ieee754.h": [
"+third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h"
],
}

View File

@ -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

View File

@ -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);

View File

@ -34,8 +34,8 @@
#include "endian.h"
#include "mydefs.h"
#include "branred.h"
#include <math.h>
#include <math_private.h>
#ifndef SECTION
# define SECTION

View File

@ -25,7 +25,7 @@
#ifndef BRANRED_H
#define BRANRED_H
#include <dla.h>
#include "dla.h"
#ifdef BIG_ENDI
static const mynumber

View File

@ -16,8 +16,6 @@
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <math.h>
/***********************************************************************/
/*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); }

View File

@ -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

View File

@ -39,11 +39,11 @@
#include "mydefs.h"
#include "usncs.h"
#include <math.h>
#include <math_private.h>
#include <fenv_private.h>
#include <math-underflow.h>
#include <libm-alias-double.h>
#include <fenv.h>
#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

View File

@ -16,8 +16,8 @@
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <mydefs.h>
#include <endian.h>
#include "mydefs.h"
#include "endian.h"
/****************************************************************/
/* TABLES FOR THE usin() and ucos() FUNCTION */

View File

@ -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