brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · 4c96a78 Raw
125 lines · c
1//===-- Implementation header for coshf16 -----------------------*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H10#define LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H11 12#include "include/llvm-libc-macros/float16-macros.h"13 14#ifdef LIBC_TYPES_HAS_FLOAT1615 16#include "expxf16_utils.h"17#include "src/__support/FPUtil/FEnvImpl.h"18#include "src/__support/FPUtil/FPBits.h"19#include "src/__support/FPUtil/except_value_utils.h"20#include "src/__support/FPUtil/rounding_mode.h"21#include "src/__support/macros/config.h"22#include "src/__support/macros/optimization.h"23 24namespace LIBC_NAMESPACE_DECL {25 26namespace math {27 28LIBC_INLINE static constexpr float16 coshf16(float16 x) {29 30#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS31  constexpr fputil::ExceptValues<float16, 9> COSHF16_EXCEPTS_POS = {{32      // x = 0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)33      {0x29a8U, 0x3c00U, 1U, 0U, 1U},34      // x = 0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ)35      {0x3e31U, 0x40eaU, 1U, 0U, 0U},36      // x = 0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ)37      {0x3e65U, 0x4126U, 1U, 0U, 0U},38      // x = 0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ)39      {0x3ed8U, 0x41b6U, 1U, 0U, 1U},40      // x = 0x1.aap+1, coshf16(x) = 0x1.be8p+3 (RZ)41      {0x42a8U, 0x4afaU, 1U, 0U, 1U},42      // x = 0x1.cc4p+1, coshf16(x) = 0x1.23cp+4 (RZ)43      {0x4331U, 0x4c8fU, 1U, 0U, 0U},44      // x = 0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ)45      {0x44a2U, 0x526dU, 1U, 0U, 0U},46      // x = 0x1.958p+2, coshf16(x) = 0x1.1a4p+8 (RZ)47      {0x4656U, 0x5c69U, 1U, 0U, 0U},48      // x = 0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)49      {0x497cU, 0x7715U, 1U, 0U, 1U},50  }};51 52  constexpr fputil::ExceptValues<float16, 6> COSHF16_EXCEPTS_NEG = {{53      // x = -0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)54      {0xa9a8U, 0x3c00U, 1U, 0U, 1U},55      // x = -0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ)56      {0xbed8U, 0x41b6U, 1U, 0U, 1U},57      // x = -0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ)58      {0xc4a2U, 0x526dU, 1U, 0U, 0U},59      // x = -0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)60      {0xc97cU, 0x7715U, 1U, 0U, 1U},61      // x = -0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ)62      {0xbe31U, 0x40eaU, 1U, 0U, 0U},63      // x = -0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ)64      {0xbe65U, 0x4126U, 1U, 0U, 0U},65  }};66#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS67 68  using namespace expxf16_internal;69  using FPBits = fputil::FPBits<float16>;70  FPBits x_bits(x);71 72  uint16_t x_u = x_bits.uintval();73  uint16_t x_abs = x_u & 0x7fffU;74 75  // When |x| >= acosh(2^16), or x is NaN.76  if (LIBC_UNLIKELY(x_abs >= 0x49e5U)) {77    // cosh(NaN) = NaN78    if (x_bits.is_nan()) {79      if (x_bits.is_signaling_nan()) {80        fputil::raise_except_if_required(FE_INVALID);81        return FPBits::quiet_nan().get_val();82      }83 84      return x;85    }86 87    // When |x| >= acosh(2^16).88    if (x_abs >= 0x49e5U) {89      // cosh(+/-inf) = +inf90      if (x_bits.is_inf())91        return FPBits::inf().get_val();92 93      switch (fputil::quick_get_round()) {94      case FE_TONEAREST:95      case FE_UPWARD:96        fputil::set_errno_if_required(ERANGE);97        fputil::raise_except_if_required(FE_OVERFLOW | FE_INEXACT);98        return FPBits::inf().get_val();99      default:100        return FPBits::max_normal().get_val();101      }102    }103  }104 105#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS106  if (x_bits.is_pos()) {107    if (auto r = COSHF16_EXCEPTS_POS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))108      return r.value();109  } else {110    if (auto r = COSHF16_EXCEPTS_NEG.lookup(x_u); LIBC_UNLIKELY(r.has_value()))111      return r.value();112  }113#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS114 115  return eval_sinh_or_cosh</*IsSinh=*/false>(x);116}117 118} // namespace math119 120} // namespace LIBC_NAMESPACE_DECL121 122#endif // LIBC_TYPES_HAS_FLOAT16123 124#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H125