Skip to content

Commit a56711d

Browse files
author
Job Hernandez
committed
add initial draft
1 parent 0751418 commit a56711d

File tree

11 files changed

+243
-2
lines changed

11 files changed

+243
-2
lines changed

libc/config/darwin/arm/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ set(TARGET_LIBM_ENTRYPOINTS
139139
libc.src.math.coshf
140140
libc.src.math.cos
141141
libc.src.math.cosf
142+
libc.src.math.cospi
142143
libc.src.math.cospif
143144
libc.src.math.dfmal
144145
libc.src.math.dsqrtl

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ set(TARGET_LIBM_ENTRYPOINTS
424424
libc.src.math.cos
425425
libc.src.math.cosf
426426
libc.src.math.coshf
427+
libc.src.math.cospi
427428
libc.src.math.cospif
428429
libc.src.math.daddl
429430
libc.src.math.ddivl

libc/include/math.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,12 @@ functions:
249249
arguments:
250250
- type: long double
251251
- type: long double
252+
- name: cospi
253+
standards:
254+
- stdc
255+
return_type: double
256+
arguments:
257+
- type: double
252258
- name: dmulf128
253259
standards:
254260
- llvm_libc_ext

libc/src/math/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ add_math_entrypoint_object(cosh)
9999
add_math_entrypoint_object(coshf)
100100
add_math_entrypoint_object(coshf16)
101101

102+
add_math_entrypoint_object(cospi)
102103
add_math_entrypoint_object(cospif)
103104
add_math_entrypoint_object(cospif16)
104105

libc/src/math/cospi.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header for cospi -------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_MATH_COSPI_H
10+
#define LLVM_LIBC_SRC_MATH_COSPI_H
11+
12+
#include "src/__support/macros/config.h"
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
16+
double cospi(double x);
17+
18+
} // namespace LIBC_NAMESPACE_DECL
19+
20+
#endif // LLVM_LIBC_SRC_MATH_SINPIF_H

libc/src/math/generic/CMakeLists.txt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
add_entrypoint_object(
42
canonicalize
53
SRCS
@@ -381,6 +379,23 @@ add_entrypoint_object(
381379
libc.src.__support.macros.optimization
382380
libc.src.__support.macros.properties.types
383381
)
382+
add_entrypoint_object(
383+
cospi
384+
SRCS
385+
cospi.cpp
386+
HDRS
387+
../cospi.h
388+
DEPENDS
389+
.sincosf_utils
390+
libc.src.__support.FPUtil.fenv_impl
391+
libc.src.__support.FPUtil.fp_bits
392+
libc.src.__support.FPUtil.fma
393+
libc.src.__support.FPUtil.multiply_add
394+
libc.src.__support.macros.optimization
395+
libc.src.__support.FPUtil.polyeval
396+
libc.src.math.pow
397+
libc.src.__support.FPUtil.basic_operations
398+
)
384399

385400
add_entrypoint_object(
386401
cospif

libc/src/math/generic/cospi.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//===-- double-precision cospi function ----------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/math/cospi.h"
10+
#include "sincos_eval.h"
11+
#include "src/__support/FPUtil/BasicOperations.h"
12+
#include "src/__support/FPUtil/FEnvImpl.h"
13+
#include "src/__support/FPUtil/FPBits.h"
14+
#include "src/__support/FPUtil/PolyEval.h"
15+
#include "src/__support/FPUtil/double_double.h"
16+
#include "src/__support/FPUtil/multiply_add.h"
17+
#include "src/__support/common.h"
18+
#include "src/__support/macros/config.h"
19+
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
20+
#include "src/math/fmul.h"
21+
#include "src/math/generic/sincosf_utils.h"
22+
#include "src/math/pow.h"
23+
24+
namespace LIBC_NAMESPACE_DECL {
25+
26+
static LIBC_INLINE void sincospi_poly_eval(double k, double y, double &sin_k,
27+
double &cos_k, double &sin_y,
28+
29+
double &cosm1_y) {
30+
31+
// Q3 = fpminimax(sin(x*pi), 7, [|64...|], [-0.0078125, 0.0078125]);
32+
sin_k =
33+
k * fputil::polyeval(k, 0x1.59b6a771a45cbab8p-94, 0x1.921fb54442d1846ap1,
34+
-0x1.8633470ba8bd806cp-76, -0x1.4abbce625be56346p2,
35+
0x1.d3e01dfd72e97a92p-61, 0x1.466bc67713dbbfp1,
36+
-0x1.14c2648595e2ad4p-47, -0x1.32d1cc20b89301fcp-1);
37+
38+
sin_y =
39+
y * fputil::polyeval(k, 0x1.59b6a771a45cbab8p-94, 0x1.921fb54442d1846ap1,
40+
-0x1.8633470ba8bd806cp-76, -0x1.4abbce625be56346p2,
41+
0x1.d3e01dfd72e97a92p-61, 0x1.466bc67713dbbfp1,
42+
-0x1.14c2648595e2ad4p-47, -0x1.32d1cc20b89301fcp-1);
43+
44+
// Q1 = fpminimax(cos(x * pi), 7, [|64...|], [-0.0078125, 0.0078125]);
45+
cos_k =
46+
k * fputil::polyeval(k, 0x1p0, 0x1.a5b22c564ee1d862p-84,
47+
-0x1.3bd3cc9be45d30e6p2, -0x1.5c2328fefbe60d3ep-66,
48+
0x1.03c1f080a6907a6p2, 0x1.569a4d5c5018eecap-51,
49+
-0x1.55d1f72455a9848ap0, -0x1.6b18e5f7fc6c39a6p-38);
50+
51+
cosm1_y =
52+
y * fputil::polyeval(y, 0x1p0, 0x1.a5b22c564ee1d862p-84,
53+
-0x1.3bd3cc9be45d30e6p2, -0x1.5c2328fefbe60d3ep-66,
54+
0x1.03c1f080a6907a6p2, 0x1.569a4d5c5018eecap-51,
55+
-0x1.55d1f72455a9848ap0, -0x1.6b18e5f7fc6c39a6p-38);
56+
}
57+
58+
LLVM_LIBC_FUNCTION(double, cospi, (double x)) {
59+
using FPBits = typename fputil::FPBits<double>;
60+
FPBits xbits(x);
61+
62+
double x_abs = fputil::abs(x);
63+
double p = 0x1p52; // 2^p where p is the precision
64+
65+
if (LIBC_UNLIKELY(x_abs == 0U))
66+
return x;
67+
68+
if (x_abs >= p) {
69+
if (xbits.is_nan())
70+
return x;
71+
if (xbits.is_inf()) {
72+
fputil::set_errno_if_required(EDOM);
73+
fputil::raise_except_if_required(FE_INVALID);
74+
return FPBits::quiet_nan().get_val();
75+
}
76+
return FPBits::zero(xbits.sign()).get_val();
77+
}
78+
double n = pow(2, -52);
79+
double k = fputil::nearest_integer(x * n);
80+
double y = x - k;
81+
double sin_k, cos_k, sin_y, cosm1_y;
82+
83+
sincospi_poly_eval(k, y, sin_k, cos_k, sin_y, cosm1_y);
84+
85+
if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0))
86+
return FPBits::zero(xbits.sign()).get_val();
87+
88+
return fputil::cast<double>(fputil::multiply_add(
89+
cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k)));
90+
}
91+
} // namespace LIBC_NAMESPACE_DECL

libc/test/src/math/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@ add_fp_unittest(
3939
libc.src.math.cosf16
4040
)
4141

42+
add_fp_unittest(
43+
cospi_test
44+
NEED_MPFR
45+
SUITE
46+
libc-math-unittests
47+
SRCS
48+
cospi_test.cpp
49+
HDRS
50+
sdcomp26094.h
51+
DEPENDS
52+
libc.src.errno.errno
53+
libc.src.math.cospi
54+
libc.src.__support.CPP.array
55+
libc.src.__support.FPUtil.fp_bits
56+
)
57+
4258
add_fp_unittest(
4359
cospif_test
4460
NEED_MPFR

libc/test/src/math/cospi_test.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===-- Exhaustive test for cospi -----------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===---------------------------------------------------------------------===//
8+
9+
#include "src/math/cospi.h"
10+
#include "test/UnitTest/FPMatcher.h"
11+
#include "test/UnitTest/Test.h"
12+
#include "utils/MPFRWrapper/MPFRUtils.h"
13+
14+
#include <iostream>
15+
16+
using LlvmLibcCospiTest = LIBC_NAMESPACE::testing::FPTest<double>;
17+
using namespace std;
18+
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
19+
20+
static constexpr double POS_START = 0;
21+
static constexpr double POS_STOP = 200;
22+
23+
TEST_F(LlvmLibcCospiTest, PositiveRange) {
24+
for (double v = POS_START; v <= POS_STOP; ++v) {
25+
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Cospi, v,
26+
LIBC_NAMESPACE::cospi(v), 0.5);
27+
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Cospi, -v,
28+
LIBC_NAMESPACE::cospi(-v), 0.5);
29+
}
30+
}

libc/test/src/math/smoke/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ add_fp_unittest(
2323
libc.src.math.cosf16
2424
)
2525

26+
add_fp_unittest(
27+
cospi_test
28+
SUITE
29+
libc-math-smoke-tests
30+
SRCS
31+
cospi_test.cpp
32+
DEPENDS
33+
libc.src.errno.errno
34+
libc.src.math.cospi
35+
libc.src.__support.CPP.array
36+
libc.src.__support.FPUtil.fp_bits
37+
)
2638
add_fp_unittest(
2739
cospif_test
2840
SUITE

0 commit comments

Comments
 (0)