Skip to content

Commit 1bb112d

Browse files
committed
add cosf16 function
1 parent 38eaea7 commit 1bb112d

File tree

13 files changed

+232
-4
lines changed

13 files changed

+232
-4
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
632632
libc.src.math.canonicalizef16
633633
libc.src.math.ceilf16
634634
libc.src.math.copysignf16
635+
libc.src.math.cosf16
635636
libc.src.math.coshf16
636637
libc.src.math.cospif16
637638
libc.src.math.exp10f16

libc/docs/headers/math/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ Higher Math Functions
276276
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
277277
| compoundn | | | | | | 7.12.7.2 | F.10.4.2 |
278278
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
279-
| cos | |check| | |check| | | | | 7.12.4.5 | F.10.1.5 |
279+
| cos | |check| | |check| | | |check| | | 7.12.4.5 | F.10.1.5 |
280280
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
281281
| cosh | |check| | | | |check| | | 7.12.5.4 | F.10.2.4 |
282282
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+

libc/hdrgen/yaml/math.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,13 @@ functions:
200200
return_type: float
201201
arguments:
202202
- type: float
203+
- name: cosf16
204+
standards:
205+
- stdc
206+
return_type: _Float16
207+
arguments:
208+
- type: _Float16
209+
guard: LIBC_TYPES_HAS_FLOAT16
203210
- name: coshf
204211
standards:
205212
- stdc

libc/src/math/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ add_math_entrypoint_object(copysignf128)
8989

9090
add_math_entrypoint_object(cos)
9191
add_math_entrypoint_object(cosf)
92+
add_math_entrypoint_object(cosf16)
9293

9394
add_math_entrypoint_object(cosh)
9495
add_math_entrypoint_object(coshf)

libc/src/math/cosf16.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for cosf16 ------------------------*- 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_COSF16_H
10+
#define LLVM_LIBC_SRC_MATH_COSF16_H
11+
12+
#include "src/__support/macros/config.h"
13+
#include "src/__support/macros/properties/types.h"
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
float16 cosf16(float16 x);
18+
19+
} // namespace LIBC_NAMESPACE_DECL
20+
21+
#endif // LLVM_LIBC_SRC_MATH_COSF16_H

libc/src/math/generic/CMakeLists.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,25 @@ add_entrypoint_object(
418418
${libc_opt_high_flag}
419419
)
420420

421+
add_entrypoint_object(
422+
cosf16
423+
SRCS
424+
cosf16.cpp
425+
HDRS
426+
../cosf16.h
427+
DEPENDS
428+
.sincosf16_utils
429+
libc.hdr.errno_macros
430+
libc.hdr.fenv_macros
431+
libc.src.__support.FPUtil.cast
432+
libc.src.__support.FPUtil.fenv_impl
433+
libc.src.__support.FPUtil.fp_bits
434+
libc.src.__support.FPUtil.except_value_utils
435+
libc.src.__support.FPUtil.multiply_add
436+
libc.src.__support.macros.optimization
437+
libc.src.__support.macros.properties.types
438+
)
439+
421440
add_entrypoint_object(
422441
cospif
423442
SRCS

libc/src/math/generic/cosf16.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//===-- Half-precision cos(x) 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/cosf16.h"
10+
#include "hdr/errno_macros.h"
11+
#include "hdr/fenv_macros.h"
12+
#include "sincosf16_utils.h"
13+
#include "src/__support/FPUtil/FEnvImpl.h"
14+
#include "src/__support/FPUtil/FPBits.h"
15+
#include "src/__support/FPUtil/cast.h"
16+
#include "src/__support/FPUtil/except_value_utils.h"
17+
#include "src/__support/FPUtil/multiply_add.h"
18+
#include "src/__support/macros/optimization.h"
19+
20+
namespace LIBC_NAMESPACE_DECL {
21+
22+
constexpr size_t N_EXCEPTS = 4;
23+
24+
constexpr fputil::ExceptValues<float16, N_EXCEPTS> COSF16_EXCEPTS{{
25+
// (input, RZ output, RU offset, RD offset, RN offset)
26+
{0x2b7c, 0x3bfc, 1, 0, 1},
27+
{0x4ac1, 0x38b5, 1, 0, 0},
28+
{0x5c49, 0xb8c6, 0, 1, 0},
29+
{0x7acc, 0xa474, 0, 1, 0},
30+
}};
31+
32+
LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) {
33+
using FPBits = fputil::FPBits<float16>;
34+
FPBits xbits(x);
35+
36+
uint16_t x_u = xbits.uintval();
37+
uint16_t x_abs = x_u & 0x7fff;
38+
float xf = x;
39+
40+
// Range reduction:
41+
// For |x| > pi/32, we perform range reduction as follows:
42+
// Find k and y such that:
43+
// x = (k + y) * pi/32
44+
// k is an integer, |y| < 0.5
45+
//
46+
// This is done by performing:
47+
// k = round(x * 32/pi)
48+
// y = x * 32/pi - k
49+
//
50+
// Once k and y are computed, we then deduce the answer by the cosine of sum
51+
// formula:
52+
// cos(x) = cos((k + y) * pi/32)
53+
// = cos(k * pi/32) * cos(y * pi/32) -
54+
// sin(k * pi/32) * sin(y * pi/32)
55+
56+
// Handle exceptional values
57+
58+
if (LIBC_UNLIKELY(x_abs == 0x2b7c || x_abs == 0x4ac1 || x_abs == 0x5c49 ||
59+
x_abs == 0x7acc)) {
60+
if (auto r = COSF16_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value()))
61+
return r.value();
62+
}
63+
64+
if (LIBC_UNLIKELY(x_abs == 0U))
65+
return fputil::cast<float16>(1.0f);
66+
67+
if (xbits.is_inf_or_nan()) {
68+
if (xbits.is_inf()) {
69+
fputil::set_errno_if_required(EDOM);
70+
fputil::raise_except_if_required(FE_INVALID);
71+
}
72+
73+
return x + FPBits::quiet_nan().get_val();
74+
}
75+
76+
float sin_k, cos_k, sin_y, cosm1_y;
77+
sincosf16_eval(xf, sin_k, cos_k, sin_y, cosm1_y);
78+
// Since, cosm1_y = cos_y - 1, therefore:
79+
// cos(x) = cos_k * cosm1_y - sin_k * sin_y
80+
return fputil::cast<float16>(fputil::multiply_add(
81+
cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k)));
82+
}
83+
84+
} // namespace LIBC_NAMESPACE_DECL

libc/src/math/generic/cospif16.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ LLVM_LIBC_FUNCTION(float16, cospif16, (float16 x)) {
7373
return fputil::cast<float16>(0.0f);
7474

7575
// Since, cosm1_y = cos_y - 1, therefore:
76-
// cos(x * pi) = cos_k(cosm1_y) + cos_k - sin_k * sin_y
76+
// cos(x * pi) = cos_k(cosm1_y) + cos_k - sin_k * sin_y
7777
return fputil::cast<float16>(fputil::multiply_add(
7878
cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k)));
7979
}

libc/src/math/generic/sinf16.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ LLVM_LIBC_FUNCTION(float16, sinf16, (float16 x)) {
9999
if (LIBC_UNLIKELY(sin_y == 0 && sin_k == 0))
100100
return FPBits::zero(xbits.sign()).get_val();
101101

102-
// Since, cosm1_y = cos_y - 1, therfore:
103-
// sin(x) = cos_k * sin_y + sin_k + (cosm1_y * sin_k)
102+
// Since, cosm1_y = cos_y - 1, therefore:
103+
// sin(x) = cos_k * sin_y + sin_k + (cosm1_y * sin_k)
104104
return fputil::cast<float16>(fputil::multiply_add(
105105
sin_y, cos_k, fputil::multiply_add(cosm1_y, sin_k, sin_k)));
106106
}

libc/test/src/math/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ add_fp_unittest(
2828
libc.src.__support.FPUtil.fp_bits
2929
)
3030

31+
add_fp_unittest(
32+
cosf16_test
33+
NEED_MPFR
34+
SUITE
35+
libc-math-unittests
36+
SRCS
37+
cosf16_test.cpp
38+
DEPENDS
39+
libc.src.math.cosf16
40+
)
41+
3142
add_fp_unittest(
3243
cospif_test
3344
NEED_MPFR

0 commit comments

Comments
 (0)