[libc][math] Refactor coshf16 implementation to header-only in src/__support/math folder. (#153582)
Part of #147386 in preparation for: https://discourse.llvm.org/t/rfc-make-clang-builtin-math-functions-constexpr-with-llvm-libc-to-support-c-23-constexpr-math-functions/86450
This commit is contained in:
parent
7ac4d9bd53
commit
2c79dc1082
@ -36,6 +36,7 @@
|
||||
#include "math/cosf.h"
|
||||
#include "math/cosf16.h"
|
||||
#include "math/coshf.h"
|
||||
#include "math/coshf16.h"
|
||||
#include "math/erff.h"
|
||||
#include "math/exp.h"
|
||||
#include "math/exp10.h"
|
||||
|
28
libc/shared/math/coshf16.h
Normal file
28
libc/shared/math/coshf16.h
Normal file
@ -0,0 +1,28 @@
|
||||
//===-- Shared coshf16 function ---------------------------------*- 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_SHARED_MATH_COSHF16_H
|
||||
#define LLVM_LIBC_SHARED_MATH_COSHF16_H
|
||||
|
||||
#include "shared/libc_common.h"
|
||||
|
||||
#ifdef LIBC_TYPES_HAS_FLOAT16
|
||||
|
||||
#include "src/__support/math/coshf16.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace shared {
|
||||
|
||||
using math::coshf16;
|
||||
|
||||
} // namespace shared
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LIBC_TYPES_HAS_FLOAT16
|
||||
|
||||
#endif // LLVM_LIBC_SHARED_MATH_COSHF16_H
|
@ -419,6 +419,19 @@ add_header_library(
|
||||
libc.src.__support.macros.optimization
|
||||
)
|
||||
|
||||
add_header_library(
|
||||
coshf16
|
||||
HDRS
|
||||
coshf16.h
|
||||
DEPENDS
|
||||
.expxf16_utils
|
||||
libc.src.__support.FPUtil.except_value_utils
|
||||
libc.src.__support.FPUtil.fenv_impl
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
libc.src.__support.FPUtil.rounding_mode
|
||||
libc.src.__support.macros.optimization
|
||||
)
|
||||
|
||||
add_header_library(
|
||||
erff
|
||||
HDRS
|
||||
@ -489,6 +502,21 @@ add_header_library(
|
||||
libc.include.llvm-libc-macros.float16_macros
|
||||
)
|
||||
|
||||
add_header_library(
|
||||
expxf16_utils
|
||||
HDRS
|
||||
expxf16_utils.h
|
||||
DEPENDS
|
||||
libc.hdr.stdint_proxy
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
libc.src.__support.FPUtil.cast
|
||||
libc.src.__support.FPUtil.multiply_add
|
||||
libc.src.__support.FPUtil.nearest_integer
|
||||
libc.src.__support.macros.attributes
|
||||
libc.src.__support.math.expf16_utils
|
||||
libc.src.__support.math.exp10_float16_constants
|
||||
)
|
||||
|
||||
add_header_library(
|
||||
frexpf128
|
||||
HDRS
|
||||
|
124
libc/src/__support/math/coshf16.h
Normal file
124
libc/src/__support/math/coshf16.h
Normal file
@ -0,0 +1,124 @@
|
||||
//===-- Implementation header for coshf16 -----------------------*- 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_COSHF16_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H
|
||||
|
||||
#include "include/llvm-libc-macros/float16-macros.h"
|
||||
|
||||
#ifdef LIBC_TYPES_HAS_FLOAT16
|
||||
|
||||
#include "expxf16_utils.h"
|
||||
#include "src/__support/FPUtil/FEnvImpl.h"
|
||||
#include "src/__support/FPUtil/FPBits.h"
|
||||
#include "src/__support/FPUtil/except_value_utils.h"
|
||||
#include "src/__support/FPUtil/rounding_mode.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
namespace math {
|
||||
|
||||
LIBC_INLINE static constexpr float16 coshf16(float16 x) {
|
||||
|
||||
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
constexpr fputil::ExceptValues<float16, 9> COSHF16_EXCEPTS_POS = {{
|
||||
// x = 0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)
|
||||
{0x29a8U, 0x3c00U, 1U, 0U, 1U},
|
||||
// x = 0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ)
|
||||
{0x3e31U, 0x40eaU, 1U, 0U, 0U},
|
||||
// x = 0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ)
|
||||
{0x3e65U, 0x4126U, 1U, 0U, 0U},
|
||||
// x = 0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ)
|
||||
{0x3ed8U, 0x41b6U, 1U, 0U, 1U},
|
||||
// x = 0x1.aap+1, coshf16(x) = 0x1.be8p+3 (RZ)
|
||||
{0x42a8U, 0x4afaU, 1U, 0U, 1U},
|
||||
// x = 0x1.cc4p+1, coshf16(x) = 0x1.23cp+4 (RZ)
|
||||
{0x4331U, 0x4c8fU, 1U, 0U, 0U},
|
||||
// x = 0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ)
|
||||
{0x44a2U, 0x526dU, 1U, 0U, 0U},
|
||||
// x = 0x1.958p+2, coshf16(x) = 0x1.1a4p+8 (RZ)
|
||||
{0x4656U, 0x5c69U, 1U, 0U, 0U},
|
||||
// x = 0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)
|
||||
{0x497cU, 0x7715U, 1U, 0U, 1U},
|
||||
}};
|
||||
|
||||
constexpr fputil::ExceptValues<float16, 6> COSHF16_EXCEPTS_NEG = {{
|
||||
// x = -0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)
|
||||
{0xa9a8U, 0x3c00U, 1U, 0U, 1U},
|
||||
// x = -0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ)
|
||||
{0xbed8U, 0x41b6U, 1U, 0U, 1U},
|
||||
// x = -0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ)
|
||||
{0xc4a2U, 0x526dU, 1U, 0U, 0U},
|
||||
// x = -0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)
|
||||
{0xc97cU, 0x7715U, 1U, 0U, 1U},
|
||||
// x = -0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ)
|
||||
{0xbe31U, 0x40eaU, 1U, 0U, 0U},
|
||||
// x = -0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ)
|
||||
{0xbe65U, 0x4126U, 1U, 0U, 0U},
|
||||
}};
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
using namespace expxf16_internal;
|
||||
using FPBits = fputil::FPBits<float16>;
|
||||
FPBits x_bits(x);
|
||||
|
||||
uint16_t x_u = x_bits.uintval();
|
||||
uint16_t x_abs = x_u & 0x7fffU;
|
||||
|
||||
// When |x| >= acosh(2^16), or x is NaN.
|
||||
if (LIBC_UNLIKELY(x_abs >= 0x49e5U)) {
|
||||
// cosh(NaN) = NaN
|
||||
if (x_bits.is_nan()) {
|
||||
if (x_bits.is_signaling_nan()) {
|
||||
fputil::raise_except_if_required(FE_INVALID);
|
||||
return FPBits::quiet_nan().get_val();
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// When |x| >= acosh(2^16).
|
||||
if (x_abs >= 0x49e5U) {
|
||||
// cosh(+/-inf) = +inf
|
||||
if (x_bits.is_inf())
|
||||
return FPBits::inf().get_val();
|
||||
|
||||
switch (fputil::quick_get_round()) {
|
||||
case FE_TONEAREST:
|
||||
case FE_UPWARD:
|
||||
fputil::set_errno_if_required(ERANGE);
|
||||
fputil::raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
|
||||
return FPBits::inf().get_val();
|
||||
default:
|
||||
return FPBits::max_normal().get_val();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
if (x_bits.is_pos()) {
|
||||
if (auto r = COSHF16_EXCEPTS_POS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
|
||||
return r.value();
|
||||
} else {
|
||||
if (auto r = COSHF16_EXCEPTS_NEG.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
|
||||
return r.value();
|
||||
}
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
return eval_sinh_or_cosh</*IsSinh=*/false>(x);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LIBC_TYPES_HAS_FLOAT16
|
||||
|
||||
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H
|
@ -21,7 +21,11 @@
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LIBC_INLINE ExpRangeReduction exp2_range_reduction(float16 x) {
|
||||
namespace math {
|
||||
|
||||
namespace expxf16_internal {
|
||||
|
||||
LIBC_INLINE static constexpr ExpRangeReduction exp2_range_reduction(float16 x) {
|
||||
// For -25 < x < 16, to compute 2^x, we perform the following range reduction:
|
||||
// find hi, mid, lo, such that:
|
||||
// x = hi + mid + lo, in which
|
||||
@ -117,7 +121,8 @@ static constexpr cpp::array<uint32_t, 32> EXP2_MID_5_BITS = {
|
||||
// The main point of these formulas is that the expensive part of calculating
|
||||
// the polynomials approximating lower parts of e^x and e^(-x) is shared and
|
||||
// only done once.
|
||||
template <bool IsSinh> LIBC_INLINE float16 eval_sinh_or_cosh(float16 x) {
|
||||
template <bool IsSinh>
|
||||
LIBC_INLINE static constexpr float16 eval_sinh_or_cosh(float16 x) {
|
||||
float xf = x;
|
||||
float kf = fputil::nearest_integer(xf * (LOG2F_E * 0x1.0p+5f));
|
||||
int x_hi_mid_p = static_cast<int>(kf);
|
||||
@ -174,7 +179,7 @@ template <bool IsSinh> LIBC_INLINE float16 eval_sinh_or_cosh(float16 x) {
|
||||
// Generated by Sollya with the following commands:
|
||||
// > display = hexadecimal;
|
||||
// > for i from 0 to 31 do print(round(log(1 + i * 2^-5), SG, RN));
|
||||
constexpr cpp::array<float, 32> LOGF_F = {
|
||||
static constexpr cpp::array<float, 32> LOGF_F = {
|
||||
0x0p+0f, 0x1.f829bp-6f, 0x1.f0a30cp-5f, 0x1.6f0d28p-4f,
|
||||
0x1.e27076p-4f, 0x1.29553p-3f, 0x1.5ff308p-3f, 0x1.9525aap-3f,
|
||||
0x1.c8ff7cp-3f, 0x1.fb9186p-3f, 0x1.1675cap-2f, 0x1.2e8e2cp-2f,
|
||||
@ -188,7 +193,7 @@ constexpr cpp::array<float, 32> LOGF_F = {
|
||||
// Generated by Sollya with the following commands:
|
||||
// > display = hexadecimal;
|
||||
// > for i from 0 to 31 do print(round(log2(1 + i * 2^-5), SG, RN));
|
||||
constexpr cpp::array<float, 32> LOG2F_F = {
|
||||
static constexpr cpp::array<float, 32> LOG2F_F = {
|
||||
0x0p+0f, 0x1.6bad38p-5f, 0x1.663f7p-4f, 0x1.08c588p-3f,
|
||||
0x1.5c01a4p-3f, 0x1.acf5e2p-3f, 0x1.fbc16cp-3f, 0x1.24407ap-2f,
|
||||
0x1.49a784p-2f, 0x1.6e221cp-2f, 0x1.91bba8p-2f, 0x1.b47ecp-2f,
|
||||
@ -202,7 +207,7 @@ constexpr cpp::array<float, 32> LOG2F_F = {
|
||||
// Generated by Sollya with the following commands:
|
||||
// > display = hexadecimal;
|
||||
// > for i from 0 to 31 do print(round(log10(1 + i * 2^-5), SG, RN));
|
||||
constexpr cpp::array<float, 32> LOG10F_F = {
|
||||
static constexpr cpp::array<float, 32> LOG10F_F = {
|
||||
0x0p+0f, 0x1.b5e908p-7f, 0x1.af5f92p-6f, 0x1.3ed11ap-5f,
|
||||
0x1.a30a9ep-5f, 0x1.02428cp-4f, 0x1.31b306p-4f, 0x1.5fe804p-4f,
|
||||
0x1.8cf184p-4f, 0x1.b8de4ep-4f, 0x1.e3bc1ap-4f, 0x1.06cbd6p-3f,
|
||||
@ -216,7 +221,7 @@ constexpr cpp::array<float, 32> LOG10F_F = {
|
||||
// Generated by Sollya with the following commands:
|
||||
// > display = hexadecimal;
|
||||
// > for i from 0 to 31 do print(round(1 / (1 + i * 2^-5), SG, RN));
|
||||
constexpr cpp::array<float, 32> ONE_OVER_F_F = {
|
||||
static constexpr cpp::array<float, 32> ONE_OVER_F_F = {
|
||||
0x1p+0f, 0x1.f07c2p-1f, 0x1.e1e1e2p-1f, 0x1.d41d42p-1f,
|
||||
0x1.c71c72p-1f, 0x1.bacf92p-1f, 0x1.af286cp-1f, 0x1.a41a42p-1f,
|
||||
0x1.99999ap-1f, 0x1.8f9c18p-1f, 0x1.861862p-1f, 0x1.7d05f4p-1f,
|
||||
@ -227,6 +232,10 @@ constexpr cpp::array<float, 32> ONE_OVER_F_F = {
|
||||
0x1.111112p-1f, 0x1.0c9714p-1f, 0x1.08421p-1f, 0x1.041042p-1f,
|
||||
};
|
||||
|
||||
} // namespace expxf16_internal
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_GENERIC_EXPXF16_H
|
@ -1395,7 +1395,6 @@ add_entrypoint_object(
|
||||
HDRS
|
||||
../exp2f16.h
|
||||
DEPENDS
|
||||
.expxf16
|
||||
libc.hdr.errno_macros
|
||||
libc.hdr.fenv_macros
|
||||
libc.src.__support.FPUtil.cast
|
||||
@ -1404,6 +1403,7 @@ add_entrypoint_object(
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
libc.src.__support.FPUtil.rounding_mode
|
||||
libc.src.__support.macros.optimization
|
||||
libc.src.__support.math.expxf16_utils
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
@ -1433,7 +1433,6 @@ add_entrypoint_object(
|
||||
HDRS
|
||||
../exp2m1f16.h
|
||||
DEPENDS
|
||||
.expxf16
|
||||
libc.hdr.errno_macros
|
||||
libc.hdr.fenv_macros
|
||||
libc.src.__support.common
|
||||
@ -1446,6 +1445,7 @@ add_entrypoint_object(
|
||||
libc.src.__support.FPUtil.rounding_mode
|
||||
libc.src.__support.macros.optimization
|
||||
libc.src.__support.macros.properties.cpu_features
|
||||
libc.src.__support.math.expxf16_utils
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
@ -1568,7 +1568,6 @@ add_entrypoint_object(
|
||||
HDRS
|
||||
../expm1f16.h
|
||||
DEPENDS
|
||||
.expxf16
|
||||
libc.hdr.errno_macros
|
||||
libc.hdr.fenv_macros
|
||||
libc.src.__support.FPUtil.cast
|
||||
@ -1579,6 +1578,7 @@ add_entrypoint_object(
|
||||
libc.src.__support.FPUtil.polyeval
|
||||
libc.src.__support.FPUtil.rounding_mode
|
||||
libc.src.__support.macros.optimization
|
||||
libc.src.__support.math.expxf16_utils
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
@ -1949,7 +1949,6 @@ add_entrypoint_object(
|
||||
HDRS
|
||||
../log10f16.h
|
||||
DEPENDS
|
||||
.expxf16
|
||||
libc.hdr.errno_macros
|
||||
libc.hdr.fenv_macros
|
||||
libc.src.__support.FPUtil.cast
|
||||
@ -1960,6 +1959,7 @@ add_entrypoint_object(
|
||||
libc.src.__support.FPUtil.polyeval
|
||||
libc.src.__support.macros.optimization
|
||||
libc.src.__support.macros.properties.cpu_features
|
||||
libc.src.__support.math.expxf16_utils
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
@ -2038,7 +2038,6 @@ add_entrypoint_object(
|
||||
HDRS
|
||||
../log2f16.h
|
||||
DEPENDS
|
||||
.expxf16
|
||||
libc.hdr.errno_macros
|
||||
libc.hdr.fenv_macros
|
||||
libc.src.__support.FPUtil.cast
|
||||
@ -2049,6 +2048,7 @@ add_entrypoint_object(
|
||||
libc.src.__support.FPUtil.polyeval
|
||||
libc.src.__support.macros.optimization
|
||||
libc.src.__support.macros.properties.cpu_features
|
||||
libc.src.__support.math.expxf16_utils
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
@ -2093,7 +2093,6 @@ add_entrypoint_object(
|
||||
HDRS
|
||||
../logf16.h
|
||||
DEPENDS
|
||||
.expxf16
|
||||
libc.hdr.errno_macros
|
||||
libc.hdr.fenv_macros
|
||||
libc.src.__support.FPUtil.cast
|
||||
@ -2104,6 +2103,7 @@ add_entrypoint_object(
|
||||
libc.src.__support.FPUtil.polyeval
|
||||
libc.src.__support.macros.optimization
|
||||
libc.src.__support.macros.properties.cpu_features
|
||||
libc.src.__support.math.expxf16_utils
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
@ -3918,14 +3918,7 @@ add_entrypoint_object(
|
||||
HDRS
|
||||
../coshf16.h
|
||||
DEPENDS
|
||||
.expxf16
|
||||
libc.hdr.errno_macros
|
||||
libc.hdr.fenv_macros
|
||||
libc.src.__support.FPUtil.except_value_utils
|
||||
libc.src.__support.FPUtil.fenv_impl
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
libc.src.__support.FPUtil.rounding_mode
|
||||
libc.src.__support.macros.optimization
|
||||
libc.src.__support.math.coshf16
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
@ -3948,7 +3941,6 @@ add_entrypoint_object(
|
||||
HDRS
|
||||
../sinhf16.h
|
||||
DEPENDS
|
||||
.expxf16
|
||||
libc.hdr.errno_macros
|
||||
libc.hdr.fenv_macros
|
||||
libc.src.__support.FPUtil.except_value_utils
|
||||
@ -3956,6 +3948,7 @@ add_entrypoint_object(
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
libc.src.__support.FPUtil.rounding_mode
|
||||
libc.src.__support.macros.optimization
|
||||
libc.src.__support.math.expxf16_utils
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
@ -3980,7 +3973,6 @@ add_entrypoint_object(
|
||||
HDRS
|
||||
../tanhf16.h
|
||||
DEPENDS
|
||||
.expxf16
|
||||
libc.hdr.fenv_macros
|
||||
libc.src.__support.CPP.array
|
||||
libc.src.__support.FPUtil.cast
|
||||
@ -3992,6 +3984,7 @@ add_entrypoint_object(
|
||||
libc.src.__support.FPUtil.polyeval
|
||||
libc.src.__support.FPUtil.rounding_mode
|
||||
libc.src.__support.macros.optimization
|
||||
libc.src.__support.math.expxf16_utils
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
@ -4956,21 +4949,6 @@ add_entrypoint_object(
|
||||
libc.src.__support.FPUtil.generic.mul
|
||||
)
|
||||
|
||||
add_header_library(
|
||||
expxf16
|
||||
HDRS
|
||||
expxf16.h
|
||||
DEPENDS
|
||||
libc.hdr.stdint_proxy
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
libc.src.__support.FPUtil.cast
|
||||
libc.src.__support.FPUtil.multiply_add
|
||||
libc.src.__support.FPUtil.nearest_integer
|
||||
libc.src.__support.macros.attributes
|
||||
libc.src.__support.math.expf16_utils
|
||||
libc.src.__support.math.exp10_float16_constants
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
bf16add
|
||||
SRCS
|
||||
|
@ -7,105 +7,10 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/math/coshf16.h"
|
||||
#include "expxf16.h"
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "hdr/fenv_macros.h"
|
||||
#include "src/__support/FPUtil/FEnvImpl.h"
|
||||
#include "src/__support/FPUtil/FPBits.h"
|
||||
#include "src/__support/FPUtil/except_value_utils.h"
|
||||
#include "src/__support/FPUtil/rounding_mode.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h"
|
||||
#include "src/__support/math/coshf16.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
static constexpr fputil::ExceptValues<float16, 9> COSHF16_EXCEPTS_POS = {{
|
||||
// x = 0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)
|
||||
{0x29a8U, 0x3c00U, 1U, 0U, 1U},
|
||||
// x = 0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ)
|
||||
{0x3e31U, 0x40eaU, 1U, 0U, 0U},
|
||||
// x = 0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ)
|
||||
{0x3e65U, 0x4126U, 1U, 0U, 0U},
|
||||
// x = 0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ)
|
||||
{0x3ed8U, 0x41b6U, 1U, 0U, 1U},
|
||||
// x = 0x1.aap+1, coshf16(x) = 0x1.be8p+3 (RZ)
|
||||
{0x42a8U, 0x4afaU, 1U, 0U, 1U},
|
||||
// x = 0x1.cc4p+1, coshf16(x) = 0x1.23cp+4 (RZ)
|
||||
{0x4331U, 0x4c8fU, 1U, 0U, 0U},
|
||||
// x = 0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ)
|
||||
{0x44a2U, 0x526dU, 1U, 0U, 0U},
|
||||
// x = 0x1.958p+2, coshf16(x) = 0x1.1a4p+8 (RZ)
|
||||
{0x4656U, 0x5c69U, 1U, 0U, 0U},
|
||||
// x = 0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)
|
||||
{0x497cU, 0x7715U, 1U, 0U, 1U},
|
||||
}};
|
||||
|
||||
static constexpr fputil::ExceptValues<float16, 6> COSHF16_EXCEPTS_NEG = {{
|
||||
// x = -0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)
|
||||
{0xa9a8U, 0x3c00U, 1U, 0U, 1U},
|
||||
// x = -0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ)
|
||||
{0xbed8U, 0x41b6U, 1U, 0U, 1U},
|
||||
// x = -0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ)
|
||||
{0xc4a2U, 0x526dU, 1U, 0U, 0U},
|
||||
// x = -0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)
|
||||
{0xc97cU, 0x7715U, 1U, 0U, 1U},
|
||||
// x = -0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ)
|
||||
{0xbe31U, 0x40eaU, 1U, 0U, 0U},
|
||||
// x = -0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ)
|
||||
{0xbe65U, 0x4126U, 1U, 0U, 0U},
|
||||
}};
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
LLVM_LIBC_FUNCTION(float16, coshf16, (float16 x)) {
|
||||
using FPBits = fputil::FPBits<float16>;
|
||||
FPBits x_bits(x);
|
||||
|
||||
uint16_t x_u = x_bits.uintval();
|
||||
uint16_t x_abs = x_u & 0x7fffU;
|
||||
|
||||
// When |x| >= acosh(2^16), or x is NaN.
|
||||
if (LIBC_UNLIKELY(x_abs >= 0x49e5U)) {
|
||||
// cosh(NaN) = NaN
|
||||
if (x_bits.is_nan()) {
|
||||
if (x_bits.is_signaling_nan()) {
|
||||
fputil::raise_except_if_required(FE_INVALID);
|
||||
return FPBits::quiet_nan().get_val();
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// When |x| >= acosh(2^16).
|
||||
if (x_abs >= 0x49e5U) {
|
||||
// cosh(+/-inf) = +inf
|
||||
if (x_bits.is_inf())
|
||||
return FPBits::inf().get_val();
|
||||
|
||||
switch (fputil::quick_get_round()) {
|
||||
case FE_TONEAREST:
|
||||
case FE_UPWARD:
|
||||
fputil::set_errno_if_required(ERANGE);
|
||||
fputil::raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
|
||||
return FPBits::inf().get_val();
|
||||
default:
|
||||
return FPBits::max_normal().get_val();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
if (x_bits.is_pos()) {
|
||||
if (auto r = COSHF16_EXCEPTS_POS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
|
||||
return r.value();
|
||||
} else {
|
||||
if (auto r = COSHF16_EXCEPTS_NEG.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
|
||||
return r.value();
|
||||
}
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
return eval_sinh_or_cosh</*IsSinh=*/false>(x);
|
||||
}
|
||||
LLVM_LIBC_FUNCTION(float16, coshf16, (float16 x)) { return math::coshf16(x); }
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
@ -7,7 +7,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/math/exp2f16.h"
|
||||
#include "expxf16.h"
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "hdr/fenv_macros.h"
|
||||
#include "src/__support/FPUtil/FEnvImpl.h"
|
||||
@ -18,6 +17,7 @@
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h"
|
||||
#include "src/__support/math/expxf16_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
@ -34,6 +34,7 @@ static constexpr fputil::ExceptValues<float16, 3> EXP2F16_EXCEPTS = {{
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
LLVM_LIBC_FUNCTION(float16, exp2f16, (float16 x)) {
|
||||
using namespace math::expxf16_internal;
|
||||
using FPBits = fputil::FPBits<float16>;
|
||||
FPBits x_bits(x);
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/math/exp2m1f16.h"
|
||||
#include "expxf16.h"
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "hdr/fenv_macros.h"
|
||||
#include "src/__support/FPUtil/FEnvImpl.h"
|
||||
@ -21,6 +20,7 @@
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h"
|
||||
#include "src/__support/macros/properties/cpu_features.h"
|
||||
#include "src/__support/math/expxf16_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
@ -76,6 +76,7 @@ static constexpr fputil::ExceptValues<float16, N_EXP2M1F16_EXCEPTS_HI>
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
LLVM_LIBC_FUNCTION(float16, exp2m1f16, (float16 x)) {
|
||||
using namespace math::expxf16_internal;
|
||||
using FPBits = fputil::FPBits<float16>;
|
||||
FPBits x_bits(x);
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/math/expm1f16.h"
|
||||
#include "expxf16.h"
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "hdr/fenv_macros.h"
|
||||
#include "src/__support/FPUtil/FEnvImpl.h"
|
||||
@ -20,6 +19,7 @@
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h"
|
||||
#include "src/__support/math/expxf16_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
@ -51,6 +51,7 @@ static constexpr fputil::ExceptValues<float16, N_EXPM1F16_EXCEPTS_HI>
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
LLVM_LIBC_FUNCTION(float16, expm1f16, (float16 x)) {
|
||||
using namespace math::expxf16_internal;
|
||||
using FPBits = fputil::FPBits<float16>;
|
||||
FPBits x_bits(x);
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/math/log10f16.h"
|
||||
#include "expxf16.h"
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "hdr/fenv_macros.h"
|
||||
#include "src/__support/FPUtil/FEnvImpl.h"
|
||||
@ -20,6 +19,7 @@
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h"
|
||||
#include "src/__support/macros/properties/cpu_features.h"
|
||||
#include "src/__support/math/expxf16_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
@ -75,6 +75,7 @@ static constexpr fputil::ExceptValues<float16, N_LOG10F16_EXCEPTS>
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
LLVM_LIBC_FUNCTION(float16, log10f16, (float16 x)) {
|
||||
using namespace math::expxf16_internal;
|
||||
using FPBits = fputil::FPBits<float16>;
|
||||
FPBits x_bits(x);
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/math/log2f16.h"
|
||||
#include "expxf16.h"
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "hdr/fenv_macros.h"
|
||||
#include "src/__support/FPUtil/FEnvImpl.h"
|
||||
@ -20,6 +19,7 @@
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h"
|
||||
#include "src/__support/macros/properties/cpu_features.h"
|
||||
#include "src/__support/math/expxf16_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
@ -61,6 +61,7 @@ static constexpr fputil::ExceptValues<float16, N_LOG2F16_EXCEPTS>
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
LLVM_LIBC_FUNCTION(float16, log2f16, (float16 x)) {
|
||||
using namespace math::expxf16_internal;
|
||||
using FPBits = fputil::FPBits<float16>;
|
||||
FPBits x_bits(x);
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/math/logf16.h"
|
||||
#include "expxf16.h"
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "hdr/fenv_macros.h"
|
||||
#include "src/__support/FPUtil/FEnvImpl.h"
|
||||
@ -20,6 +19,7 @@
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h"
|
||||
#include "src/__support/macros/properties/cpu_features.h"
|
||||
#include "src/__support/math/expxf16_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
@ -68,6 +68,7 @@ static constexpr fputil::ExceptValues<float16, N_LOGF16_EXCEPTS>
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
LLVM_LIBC_FUNCTION(float16, logf16, (float16 x)) {
|
||||
using namespace math::expxf16_internal;
|
||||
using FPBits = fputil::FPBits<float16>;
|
||||
FPBits x_bits(x);
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/math/sinhf16.h"
|
||||
#include "expxf16.h"
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "hdr/fenv_macros.h"
|
||||
#include "src/__support/FPUtil/FEnvImpl.h"
|
||||
@ -17,6 +16,7 @@
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h"
|
||||
#include "src/__support/math/expxf16_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
@ -89,6 +89,7 @@ static constexpr fputil::ExceptValues<float16, 13> SINHF16_EXCEPTS_NEG = {{
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
LLVM_LIBC_FUNCTION(float16, sinhf16, (float16 x)) {
|
||||
using namespace math::expxf16_internal;
|
||||
using FPBits = fputil::FPBits<float16>;
|
||||
FPBits x_bits(x);
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/math/tanhf16.h"
|
||||
#include "expxf16.h"
|
||||
#include "hdr/fenv_macros.h"
|
||||
#include "src/__support/CPP/array.h"
|
||||
#include "src/__support/FPUtil/FEnvImpl.h"
|
||||
@ -21,6 +20,7 @@
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h"
|
||||
#include "src/__support/math/expxf16_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
@ -34,6 +34,7 @@ static constexpr fputil::ExceptValues<float16, 2> TANHF16_EXCEPTS = {{
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
LLVM_LIBC_FUNCTION(float16, tanhf16, (float16 x)) {
|
||||
using namespace math::expxf16_internal;
|
||||
using FPBits = fputil::FPBits<float16>;
|
||||
FPBits x_bits(x);
|
||||
|
||||
|
@ -32,6 +32,7 @@ add_fp_unittest(
|
||||
libc.src.__support.math.cosf
|
||||
libc.src.__support.math.cosf16
|
||||
libc.src.__support.math.coshf
|
||||
libc.src.__support.math.coshf16
|
||||
libc.src.__support.math.erff
|
||||
libc.src.__support.math.exp
|
||||
libc.src.__support.math.exp10
|
||||
|
@ -22,6 +22,7 @@ TEST(LlvmLibcSharedMathTest, AllFloat16) {
|
||||
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::atanf16(0.0f16));
|
||||
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::atanhf16(0.0f16));
|
||||
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::cosf16(0.0f16));
|
||||
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::coshf16(0.0f16));
|
||||
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::exp10f16(0.0f16));
|
||||
|
||||
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::expf16(0.0f16));
|
||||
|
@ -1980,18 +1980,6 @@ libc_support_library(
|
||||
],
|
||||
)
|
||||
|
||||
libc_support_library(
|
||||
name = "expxf16",
|
||||
hdrs = ["src/math/generic/expxf16.h"],
|
||||
deps = [
|
||||
":__support_fputil_cast",
|
||||
":__support_fputil_fp_bits",
|
||||
":__support_fputil_nearest_integer",
|
||||
":__support_math_exp10_float16_constants",
|
||||
":__support_math_expf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
libc_support_library(
|
||||
name = "__support_math_acos",
|
||||
hdrs = ["src/__support/math/acos.h"],
|
||||
@ -2390,6 +2378,20 @@ libc_support_library(
|
||||
],
|
||||
)
|
||||
|
||||
libc_support_library(
|
||||
name = "__support_math_coshf16",
|
||||
hdrs = ["src/__support/math/coshf16.h"],
|
||||
deps = [
|
||||
":__support_fputil_except_value_utils",
|
||||
":__support_fputil_fenv_impl",
|
||||
":__support_fputil_fp_bits",
|
||||
":__support_fputil_rounding_mode",
|
||||
":__support_macros_config",
|
||||
":__support_macros_optimization",
|
||||
":__support_math_expxf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
libc_support_library(
|
||||
name = "__support_math_erff",
|
||||
hdrs = ["src/__support/math/erff.h"],
|
||||
@ -2461,6 +2463,18 @@ libc_support_library(
|
||||
],
|
||||
)
|
||||
|
||||
libc_support_library(
|
||||
name = "__support_math_expxf16_utils",
|
||||
hdrs = ["src/__support/math/expxf16_utils.h"],
|
||||
deps = [
|
||||
":__support_fputil_cast",
|
||||
":__support_fputil_fp_bits",
|
||||
":__support_fputil_nearest_integer",
|
||||
":__support_math_exp10_float16_constants",
|
||||
":__support_math_expf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
libc_support_library(
|
||||
name = "__support_math_frexpf128",
|
||||
hdrs = ["src/__support/math/frexpf128.h"],
|
||||
@ -3199,7 +3213,7 @@ libc_math_function(
|
||||
libc_math_function(
|
||||
name = "coshf16",
|
||||
additional_deps = [
|
||||
":expxf16",
|
||||
":__support_math_coshf16",
|
||||
],
|
||||
)
|
||||
|
||||
@ -3297,7 +3311,7 @@ libc_math_function(
|
||||
name = "expf16",
|
||||
additional_deps = [
|
||||
":__support_math_expf16",
|
||||
":expxf16",
|
||||
":__support_math_expxf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
@ -3366,7 +3380,7 @@ libc_math_function(
|
||||
libc_math_function(
|
||||
name = "exp2f16",
|
||||
additional_deps = [
|
||||
":expxf16",
|
||||
":__support_math_expxf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
@ -3381,7 +3395,7 @@ libc_math_function(
|
||||
libc_math_function(
|
||||
name = "exp2m1f16",
|
||||
additional_deps = [
|
||||
":expxf16",
|
||||
":__support_math_expxf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
@ -3417,7 +3431,7 @@ libc_math_function(
|
||||
libc_math_function(
|
||||
name = "expm1f16",
|
||||
additional_deps = [
|
||||
":expxf16",
|
||||
":__support_math_expxf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
@ -3923,7 +3937,7 @@ libc_math_function(
|
||||
libc_math_function(
|
||||
name = "logf16",
|
||||
additional_deps = [
|
||||
":expxf16",
|
||||
":__support_math_expxf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
@ -3958,7 +3972,7 @@ libc_math_function(
|
||||
libc_math_function(
|
||||
name = "log10f16",
|
||||
additional_deps = [
|
||||
":expxf16",
|
||||
":__support_math_expxf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
@ -4019,7 +4033,7 @@ libc_math_function(
|
||||
libc_math_function(
|
||||
name = "log2f16",
|
||||
additional_deps = [
|
||||
":expxf16",
|
||||
":__support_math_expxf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
@ -4341,7 +4355,7 @@ libc_math_function(
|
||||
libc_math_function(
|
||||
name = "sinhf16",
|
||||
additional_deps = [
|
||||
":expxf16",
|
||||
":__support_math_expxf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
@ -4448,7 +4462,7 @@ libc_math_function(
|
||||
libc_math_function(
|
||||
name = "tanhf16",
|
||||
additional_deps = [
|
||||
":expxf16",
|
||||
":__support_math_expxf16_utils",
|
||||
],
|
||||
)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user