diff options
Diffstat (limited to 'libc/src')
| -rw-r--r-- | libc/src/__support/math/CMakeLists.txt | 27 | ||||
| -rw-r--r-- | libc/src/__support/math/cosf16.h | 106 | ||||
| -rw-r--r-- | libc/src/__support/math/sincosf16_utils.h (renamed from libc/src/math/generic/sincosf16_utils.h) | 6 | ||||
| -rw-r--r-- | libc/src/math/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | libc/src/math/bf16fma.h | 21 | ||||
| -rw-r--r-- | libc/src/math/bf16fmaf.h | 21 | ||||
| -rw-r--r-- | libc/src/math/bf16fmaf128.h | 21 | ||||
| -rw-r--r-- | libc/src/math/bf16fmal.h | 21 | ||||
| -rw-r--r-- | libc/src/math/generic/CMakeLists.txt | 95 | ||||
| -rw-r--r-- | libc/src/math/generic/bf16fma.cpp | 21 | ||||
| -rw-r--r-- | libc/src/math/generic/bf16fmaf.cpp | 21 | ||||
| -rw-r--r-- | libc/src/math/generic/bf16fmaf128.cpp | 22 | ||||
| -rw-r--r-- | libc/src/math/generic/bf16fmal.cpp | 22 | ||||
| -rw-r--r-- | libc/src/math/generic/cosf16.cpp | 81 | ||||
| -rw-r--r-- | libc/src/math/generic/cospif16.cpp | 3 | ||||
| -rw-r--r-- | libc/src/math/generic/sinf16.cpp | 3 | ||||
| -rw-r--r-- | libc/src/math/generic/sinpif16.cpp | 3 | ||||
| -rw-r--r-- | libc/src/math/generic/tanf16.cpp | 3 | ||||
| -rw-r--r-- | libc/src/math/generic/tanpif16.cpp | 3 |
19 files changed, 391 insertions, 114 deletions
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt index 2cd064591e97..f4a8ee0fbb41 100644 --- a/libc/src/__support/math/CMakeLists.txt +++ b/libc/src/__support/math/CMakeLists.txt @@ -391,6 +391,23 @@ add_header_library( ) add_header_library( + cosf16 + HDRS + cosf16.h + DEPENDS + .sincosf16_utils + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.except_value_utils + libc.src.__support.FPUtil.multiply_add + libc.src.__support.macros.optimization + libc.src.__support.macros.properties.types +) + +add_header_library( erff HDRS erff.h @@ -699,3 +716,13 @@ add_header_library( libc.src.__support.FPUtil.polyeval libc.src.__support.common ) + +add_header_library( + sincosf16_utils + HDRS + sincosf16_utils.h + DEPENDS + libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.nearest_integer + libc.src.__support.common +) diff --git a/libc/src/__support/math/cosf16.h b/libc/src/__support/math/cosf16.h new file mode 100644 index 000000000000..50c9a8f765c2 --- /dev/null +++ b/libc/src/__support/math/cosf16.h @@ -0,0 +1,106 @@ +//===-- Implementation header for cosf16 ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COSF16_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_COSF16_H + +#include "include/llvm-libc-macros/float16-macros.h" + +#ifdef LIBC_TYPES_HAS_FLOAT16 + +#include "sincosf16_utils.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/cast.h" +#include "src/__support/FPUtil/except_value_utils.h" +#include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/macros/optimization.h" + +namespace LIBC_NAMESPACE_DECL { + +namespace math { + +LIBC_INLINE static constexpr float16 cosf16(float16 x) { +#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS + constexpr size_t N_EXCEPTS = 4; + + constexpr fputil::ExceptValues<float16, N_EXCEPTS> COSF16_EXCEPTS{{ + // (input, RZ output, RU offset, RD offset, RN offset) + {0x2b7c, 0x3bfc, 1, 0, 1}, + {0x4ac1, 0x38b5, 1, 0, 0}, + {0x5c49, 0xb8c6, 0, 1, 0}, + {0x7acc, 0xa474, 0, 1, 0}, + }}; +#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS + + using namespace sincosf16_internal; + using FPBits = fputil::FPBits<float16>; + FPBits xbits(x); + + uint16_t x_u = xbits.uintval(); + uint16_t x_abs = x_u & 0x7fff; + float xf = x; + + // Range reduction: + // For |x| > pi/32, we perform range reduction as follows: + // Find k and y such that: + // x = (k + y) * pi/32 + // k is an integer, |y| < 0.5 + // + // This is done by performing: + // k = round(x * 32/pi) + // y = x * 32/pi - k + // + // Once k and y are computed, we then deduce the answer by the cosine of sum + // formula: + // cos(x) = cos((k + y) * pi/32) + // = cos(k * pi/32) * cos(y * pi/32) - + // sin(k * pi/32) * sin(y * pi/32) + +#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS + // Handle exceptional values + if (auto r = COSF16_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value())) + return r.value(); +#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS + + // cos(+/-0) = 1 + if (LIBC_UNLIKELY(x_abs == 0U)) + return fputil::cast<float16>(1.0f); + + // cos(+/-inf) = NaN, and cos(NaN) = NaN + if (xbits.is_inf_or_nan()) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + + if (xbits.is_inf()) { + fputil::set_errno_if_required(EDOM); + fputil::raise_except_if_required(FE_INVALID); + } + + return x + FPBits::quiet_nan().get_val(); + } + + float sin_k = 0.0f, cos_k = 0.0f, sin_y = 0.0f, cosm1_y = 0.0f; + sincosf16_eval(xf, sin_k, cos_k, sin_y, cosm1_y); + // Since, cosm1_y = cos_y - 1, therefore: + // cos(x) = cos_k * cos_y - sin_k * sin_y + // = cos_k * (cos_y - 1 + 1) - sin_k * sin_y + // = cos_k * cosm1_y - sin_k * sin_y + cos_k + return fputil::cast<float16>(fputil::multiply_add( + cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k))); +} + +} // namespace math + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_FLOAT16 + +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSF16_H diff --git a/libc/src/math/generic/sincosf16_utils.h b/libc/src/__support/math/sincosf16_utils.h index 05cab09d2089..74f21fd0a9dc 100644 --- a/libc/src/math/generic/sincosf16_utils.h +++ b/libc/src/__support/math/sincosf16_utils.h @@ -16,6 +16,8 @@ namespace LIBC_NAMESPACE_DECL { +namespace sincosf16_internal { + // Lookup table for sin(k * pi / 32) with k = 0, ..., 63. // Table is generated with Sollya as follows: // > display = hexadecimmal; @@ -66,7 +68,7 @@ LIBC_INLINE int32_t range_reduction_sincosf16(float x, float &y) { return static_cast<int32_t>(kd); } -static LIBC_INLINE void sincosf16_poly_eval(int32_t k, float y, float &sin_k, +LIBC_INLINE static void sincosf16_poly_eval(int32_t k, float y, float &sin_k, float &cos_k, float &sin_y, float &cosm1_y) { @@ -107,6 +109,8 @@ LIBC_INLINE void sincospif16_eval(float xf, float &sin_k, float &cos_k, sincosf16_poly_eval(k, y, sin_k, cos_k, sin_y, cosm1_y); } +} // namespace sincosf16_internal + } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC_SRC_MATH_GENERIC_SINCOSF16_UTILS_H diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index 2cf5ae5eab72..8db5901afa9c 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -584,6 +584,11 @@ add_math_entrypoint_object(bf16divf) add_math_entrypoint_object(bf16divl) add_math_entrypoint_object(bf16divf128) +add_math_entrypoint_object(bf16fma) +add_math_entrypoint_object(bf16fmaf) +add_math_entrypoint_object(bf16fmal) +add_math_entrypoint_object(bf16fmaf128) + add_math_entrypoint_object(bf16mul) add_math_entrypoint_object(bf16mulf) add_math_entrypoint_object(bf16mull) diff --git a/libc/src/math/bf16fma.h b/libc/src/math/bf16fma.h new file mode 100644 index 000000000000..aa54956ef478 --- /dev/null +++ b/libc/src/math/bf16fma.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16fma -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16FMA_H +#define LLVM_LIBC_SRC_MATH_BF16FMA_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16fma(double x, double y, double z); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16FMA_H diff --git a/libc/src/math/bf16fmaf.h b/libc/src/math/bf16fmaf.h new file mode 100644 index 000000000000..e8582bd6dff5 --- /dev/null +++ b/libc/src/math/bf16fmaf.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16fmaf ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16FMAF_H +#define LLVM_LIBC_SRC_MATH_BF16FMAF_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16fmaf(float x, float y, float z); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16FMAF_H diff --git a/libc/src/math/bf16fmaf128.h b/libc/src/math/bf16fmaf128.h new file mode 100644 index 000000000000..4215e54c82ff --- /dev/null +++ b/libc/src/math/bf16fmaf128.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16fmaf128 -------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16FMAF128_H +#define LLVM_LIBC_SRC_MATH_BF16FMAF128_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16fmaf128(float128 x, float128 y, float128 z); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16FMAF128_H diff --git a/libc/src/math/bf16fmal.h b/libc/src/math/bf16fmal.h new file mode 100644 index 000000000000..b92f17b7ee8d --- /dev/null +++ b/libc/src/math/bf16fmal.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16fmal ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16FMAL_H +#define LLVM_LIBC_SRC_MATH_BF16FMAL_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16fmal(long double x, long double y, long double z); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16FMAL_H diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index 70e5bf682ed9..e12bee4ab8f4 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -278,16 +278,6 @@ add_entrypoint_object( libc.src.__support.FPUtil.generic.add_sub ) -add_header_library( - sincosf16_utils - HDRS - sincosf16_utils.h - DEPENDS - libc.src.__support.FPUtil.polyeval - libc.src.__support.FPUtil.nearest_integer - libc.src.__support.common -) - add_entrypoint_object( cos SRCS @@ -315,16 +305,7 @@ add_entrypoint_object( HDRS ../cosf16.h DEPENDS - .sincosf16_utils - libc.hdr.errno_macros - libc.hdr.fenv_macros - libc.src.__support.FPUtil.cast - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.except_value_utils - libc.src.__support.FPUtil.multiply_add - libc.src.__support.macros.optimization - libc.src.__support.macros.properties.types + libc.src.__support.math.cosf16 ) add_entrypoint_object( @@ -349,7 +330,6 @@ add_entrypoint_object( HDRS ../cospif16.h DEPENDS - .sincosf16_utils libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -357,6 +337,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.multiply_add libc.src.__support.macros.optimization + libc.src.__support.math.sincosf16_utils ) add_entrypoint_object( @@ -405,7 +386,6 @@ add_entrypoint_object( HDRS ../sinf16.h DEPENDS - .sincosf16_utils libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -415,6 +395,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.multiply_add libc.src.__support.macros.optimization libc.src.__support.macros.properties.types + libc.src.__support.math.sincosf16_utils COMPILE_OPTIONS ${libc_opt_high_flag} ) @@ -482,7 +463,6 @@ add_entrypoint_object( HDRS ../sinpif16.h DEPENDS - .sincosf16_utils libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -490,6 +470,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.multiply_add libc.src.__support.macros.optimization + libc.src.__support.math.sincosf16_utils ) add_entrypoint_object( @@ -538,7 +519,6 @@ add_entrypoint_object( HDRS ../tanf16.h DEPENDS - .sincosf16_utils libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -548,6 +528,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.multiply_add libc.src.__support.macros.optimization libc.src.__support.macros.properties.types + libc.src.__support.math.sincosf16_utils ) add_entrypoint_object( @@ -572,7 +553,6 @@ add_entrypoint_object( HDRS ../tanpif16.h DEPENDS - .sincosf16_utils libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -581,6 +561,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.except_value_utils libc.src.__support.FPUtil.multiply_add libc.src.__support.macros.optimization + libc.src.__support.math.sincosf16_utils ) add_entrypoint_object( @@ -5106,15 +5087,57 @@ add_entrypoint_object( ) add_entrypoint_object( - bf16sub + bf16fma SRCS - bf16sub.cpp + bf16fma.cpp HDRS - ../bf16sub.h + ../bf16fma.h DEPENDS libc.src.__support.common libc.src.__support.FPUtil.bfloat16 - libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.FPUtil.fma + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16fmaf + SRCS + bf16fmaf.cpp + HDRS + ../bf16fmaf.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fma + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16fmal + SRCS + bf16fmal.cpp + HDRS + ../bf16fmal.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fma + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16fmaf128 + SRCS + bf16fmaf128.cpp + HDRS + ../bf16fmaf128.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fma libc.src.__support.macros.config libc.src.__support.macros.properties.types ) @@ -5176,6 +5199,20 @@ add_entrypoint_object( ) add_entrypoint_object( + bf16sub + SRCS + bf16sub.cpp + HDRS + ../bf16sub.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( bf16subf SRCS bf16subf.cpp diff --git a/libc/src/math/generic/bf16fma.cpp b/libc/src/math/generic/bf16fma.cpp new file mode 100644 index 000000000000..0f0fe8658dde --- /dev/null +++ b/libc/src/math/generic/bf16fma.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16fma function --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16fma.h" +#include "src/__support/FPUtil/FMA.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16fma, (double x, double y, double z)) { + return fputil::fma<bfloat16>(x, y, z); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16fmaf.cpp b/libc/src/math/generic/bf16fmaf.cpp new file mode 100644 index 000000000000..739691cc5011 --- /dev/null +++ b/libc/src/math/generic/bf16fmaf.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16fmaf function -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16fmaf.h" +#include "src/__support/FPUtil/FMA.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16fmaf, (float x, float y, float z)) { + return fputil::fma<bfloat16>(x, y, z); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16fmaf128.cpp b/libc/src/math/generic/bf16fmaf128.cpp new file mode 100644 index 000000000000..a29a0b0b2727 --- /dev/null +++ b/libc/src/math/generic/bf16fmaf128.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of bf16fmaf128 function ----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16fmaf128.h" +#include "src/__support/FPUtil/FMA.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16fmaf128, + (float128 x, float128 y, float128 z)) { + return fputil::fma<bfloat16>(x, y, z); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16fmal.cpp b/libc/src/math/generic/bf16fmal.cpp new file mode 100644 index 000000000000..f31ec6904760 --- /dev/null +++ b/libc/src/math/generic/bf16fmal.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of bf16fmal function -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16fmal.h" + +#include "src/__support/FPUtil/FMA.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16fmal, + (long double x, long double y, long double z)) { + return fputil::fma<bfloat16>(x, y, z); +} +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/cosf16.cpp b/libc/src/math/generic/cosf16.cpp index 99bb03eb7142..031c3e131d97 100644 --- a/libc/src/math/generic/cosf16.cpp +++ b/libc/src/math/generic/cosf16.cpp @@ -7,87 +7,10 @@ //===----------------------------------------------------------------------===// #include "src/math/cosf16.h" -#include "hdr/errno_macros.h" -#include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/FPUtil/cast.h" -#include "src/__support/FPUtil/except_value_utils.h" -#include "src/__support/FPUtil/multiply_add.h" -#include "src/__support/macros/optimization.h" +#include "src/__support/math/cosf16.h" namespace LIBC_NAMESPACE_DECL { -#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS -constexpr size_t N_EXCEPTS = 4; - -constexpr fputil::ExceptValues<float16, N_EXCEPTS> COSF16_EXCEPTS{{ - // (input, RZ output, RU offset, RD offset, RN offset) - {0x2b7c, 0x3bfc, 1, 0, 1}, - {0x4ac1, 0x38b5, 1, 0, 0}, - {0x5c49, 0xb8c6, 0, 1, 0}, - {0x7acc, 0xa474, 0, 1, 0}, -}}; -#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS - -LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) { - using FPBits = fputil::FPBits<float16>; - FPBits xbits(x); - - uint16_t x_u = xbits.uintval(); - uint16_t x_abs = x_u & 0x7fff; - float xf = x; - - // Range reduction: - // For |x| > pi/32, we perform range reduction as follows: - // Find k and y such that: - // x = (k + y) * pi/32 - // k is an integer, |y| < 0.5 - // - // This is done by performing: - // k = round(x * 32/pi) - // y = x * 32/pi - k - // - // Once k and y are computed, we then deduce the answer by the cosine of sum - // formula: - // cos(x) = cos((k + y) * pi/32) - // = cos(k * pi/32) * cos(y * pi/32) - - // sin(k * pi/32) * sin(y * pi/32) - -#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS - // Handle exceptional values - if (auto r = COSF16_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value())) - return r.value(); -#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS - - // cos(+/-0) = 1 - if (LIBC_UNLIKELY(x_abs == 0U)) - return fputil::cast<float16>(1.0f); - - // cos(+/-inf) = NaN, and cos(NaN) = NaN - if (xbits.is_inf_or_nan()) { - if (xbits.is_signaling_nan()) { - fputil::raise_except_if_required(FE_INVALID); - return FPBits::quiet_nan().get_val(); - } - - if (xbits.is_inf()) { - fputil::set_errno_if_required(EDOM); - fputil::raise_except_if_required(FE_INVALID); - } - - return x + FPBits::quiet_nan().get_val(); - } - - float sin_k, cos_k, sin_y, cosm1_y; - sincosf16_eval(xf, sin_k, cos_k, sin_y, cosm1_y); - // Since, cosm1_y = cos_y - 1, therefore: - // cos(x) = cos_k * cos_y - sin_k * sin_y - // = cos_k * (cos_y - 1 + 1) - sin_k * sin_y - // = cos_k * cosm1_y - sin_k * sin_y + cos_k - return fputil::cast<float16>(fputil::multiply_add( - cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k))); -} +LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) { return math::cosf16(x); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/cospif16.cpp b/libc/src/math/generic/cospif16.cpp index 9dc25920d5cf..c99285b25c10 100644 --- a/libc/src/math/generic/cospif16.cpp +++ b/libc/src/math/generic/cospif16.cpp @@ -9,16 +9,17 @@ #include "src/math/cospif16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/macros/optimization.h" +#include "src/__support/math/sincosf16_utils.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(float16, cospif16, (float16 x)) { + using namespace sincosf16_internal; using FPBits = typename fputil::FPBits<float16>; FPBits xbits(x); diff --git a/libc/src/math/generic/sinf16.cpp b/libc/src/math/generic/sinf16.cpp index 28debbd52a9a..2b579202ea11 100644 --- a/libc/src/math/generic/sinf16.cpp +++ b/libc/src/math/generic/sinf16.cpp @@ -9,13 +9,13 @@ #include "src/math/sinf16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/except_value_utils.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/macros/optimization.h" +#include "src/__support/math/sincosf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -32,6 +32,7 @@ constexpr fputil::ExceptValues<float16, N_EXCEPTS> SINF16_EXCEPTS{{ #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, sinf16, (float16 x)) { + using namespace sincosf16_internal; using FPBits = fputil::FPBits<float16>; FPBits xbits(x); diff --git a/libc/src/math/generic/sinpif16.cpp b/libc/src/math/generic/sinpif16.cpp index 68af484a6c5d..311e6f989ebf 100644 --- a/libc/src/math/generic/sinpif16.cpp +++ b/libc/src/math/generic/sinpif16.cpp @@ -9,15 +9,16 @@ #include "src/math/sinpif16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/math/sincosf16_utils.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(float16, sinpif16, (float16 x)) { + using namespace sincosf16_internal; using FPBits = typename fputil::FPBits<float16>; FPBits xbits(x); diff --git a/libc/src/math/generic/tanf16.cpp b/libc/src/math/generic/tanf16.cpp index 229f4a363670..20323a88f352 100644 --- a/libc/src/math/generic/tanf16.cpp +++ b/libc/src/math/generic/tanf16.cpp @@ -9,13 +9,13 @@ #include "src/math/tanf16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/except_value_utils.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/macros/optimization.h" +#include "src/__support/math/sincosf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -37,6 +37,7 @@ constexpr fputil::ExceptValues<float16, N_EXCEPTS> TANF16_EXCEPTS{{ #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, tanf16, (float16 x)) { + using namespace sincosf16_internal; using FPBits = fputil::FPBits<float16>; FPBits xbits(x); diff --git a/libc/src/math/generic/tanpif16.cpp b/libc/src/math/generic/tanpif16.cpp index 792d405b1bb9..b137b09860f7 100644 --- a/libc/src/math/generic/tanpif16.cpp +++ b/libc/src/math/generic/tanpif16.cpp @@ -9,13 +9,13 @@ #include "src/math/tanpif16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/except_value_utils.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/macros/optimization.h" +#include "src/__support/math/sincosf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -39,6 +39,7 @@ constexpr fputil::ExceptValues<float16, N_EXCEPTS> TANPIF16_EXCEPTS{{ #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, tanpif16, (float16 x)) { + using namespace sincosf16_internal; using FPBits = typename fputil::FPBits<float16>; FPBits xbits(x); |
