72 lines · c
1//===-- Implementation header for rsqrtf ------------------------*- 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_RSQRTF_H10#define LLVM_LIBC_SRC___SUPPORT_MATH_RSQRTF_H11 12#include "hdr/errno_macros.h"13#include "hdr/fenv_macros.h"14#include "src/__support/FPUtil/FEnvImpl.h"15#include "src/__support/FPUtil/FPBits.h"16#include "src/__support/FPUtil/cast.h"17#include "src/__support/FPUtil/sqrt.h"18#include "src/__support/macros/optimization.h"19 20namespace LIBC_NAMESPACE_DECL {21namespace math {22 23LIBC_INLINE static constexpr float rsqrtf(float x) {24 using FPBits = fputil::FPBits<float>;25 FPBits xbits(x);26 27 uint32_t x_u = xbits.uintval();28 uint32_t x_abs = x_u & 0x7fff'ffffU;29 30 constexpr uint32_t INF_BITS = FPBits::inf().uintval();31 32 // x is 0, inf/nan, or negative.33 if (LIBC_UNLIKELY(x_u == 0 || x_u >= INF_BITS)) {34 // x is NaN35 if (x_abs > INF_BITS) {36 if (xbits.is_signaling_nan()) {37 fputil::raise_except_if_required(FE_INVALID);38 return FPBits::quiet_nan().get_val();39 }40 return x;41 }42 43 // |x| = 044 if (x_abs == 0) {45 fputil::raise_except_if_required(FE_DIVBYZERO);46 fputil::set_errno_if_required(ERANGE);47 return FPBits::inf(xbits.sign()).get_val();48 }49 50 // -inf <= x < 051 if (x_u > 0x7fff'ffffU) {52 fputil::raise_except_if_required(FE_INVALID);53 fputil::set_errno_if_required(EDOM);54 return FPBits::quiet_nan().get_val();55 }56 57 // x = +inf => rsqrt(x) = 058 return FPBits::zero(xbits.sign()).get_val();59 }60 61 // TODO: add float based approximation when62 // LIBC_TARGET_CPU_HAS_FPU_DOUBLE is not defined63 double result = 1.0 / fputil::sqrt<double>(fputil::cast<double>(x));64 65 return fputil::cast<float>(result);66}67 68} // namespace math69} // namespace LIBC_NAMESPACE_DECL70 71#endif // LLVM_LIBC_SRC___SUPPORT_MATH_RSQRTF_H72