138 lines · c
1//===-- Floating point environment manipulation functions -------*- 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_FPUTIL_FENVIMPL_H10#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FENVIMPL_H11 12#include "hdr/fenv_macros.h"13#include "hdr/math_macros.h"14#include "hdr/types/fenv_t.h"15#include "src/__support/CPP/type_traits.h"16#include "src/__support/libc_errno.h"17#include "src/__support/macros/attributes.h" // LIBC_INLINE18#include "src/__support/macros/config.h"19#include "src/__support/macros/optimization.h"20#include "src/__support/macros/properties/architectures.h"21#include "src/__support/macros/properties/compiler.h"22 23#if defined(LIBC_TARGET_ARCH_IS_AARCH64) && defined(__ARM_FP)24#if defined(__APPLE__)25#include "aarch64/fenv_darwin_impl.h"26#else27#include "aarch64/FEnvImpl.h"28#endif29 30// The extra !defined(APPLE) condition is to cause x86_64 MacOS builds to use31// the dummy implementations below. Once a proper x86_64 darwin fenv is set up,32// the apple condition here should be removed.33// TODO: fully support fenv for MSVC.34#elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__) && \35 !defined(LIBC_COMPILER_IS_MSVC)36#include "x86_64/FEnvImpl.h"37#elif defined(LIBC_TARGET_ARCH_IS_ARM) && defined(__ARM_FP) && \38 !defined(LIBC_COMPILER_IS_MSVC)39#include "arm/FEnvImpl.h"40#elif defined(LIBC_TARGET_ARCH_IS_ANY_RISCV) && defined(__riscv_flen)41#include "riscv/FEnvImpl.h"42#else43 44namespace LIBC_NAMESPACE_DECL {45namespace fputil {46 47// All dummy functions silently succeed.48 49LIBC_INLINE int clear_except(int) { return 0; }50 51LIBC_INLINE int test_except(int) { return 0; }52 53LIBC_INLINE int get_except() { return 0; }54 55LIBC_INLINE int set_except(int) { return 0; }56 57LIBC_INLINE int raise_except(int) { return 0; }58 59LIBC_INLINE int enable_except(int) { return 0; }60 61LIBC_INLINE int disable_except(int) { return 0; }62 63LIBC_INLINE int get_round() { return FE_TONEAREST; }64 65LIBC_INLINE int set_round(int rounding_mode) {66 return (rounding_mode == FE_TONEAREST) ? 0 : 1;67}68 69LIBC_INLINE int get_env(fenv_t *) { return 0; }70 71LIBC_INLINE int set_env(const fenv_t *) { return 0; }72 73} // namespace fputil74} // namespace LIBC_NAMESPACE_DECL75#endif76 77namespace LIBC_NAMESPACE_DECL {78namespace fputil {79 80LIBC_INLINE static constexpr int81clear_except_if_required([[maybe_unused]] int excepts) {82 if (cpp::is_constant_evaluated()) {83 return 0;84 } else {85#ifndef LIBC_MATH_HAS_NO_EXCEPT86 if (math_errhandling & MATH_ERREXCEPT)87 return clear_except(excepts);88#endif // LIBC_MATH_HAS_NO_EXCEPT89 return 0;90 }91}92 93LIBC_INLINE static constexpr int94set_except_if_required([[maybe_unused]] int excepts) {95 if (cpp::is_constant_evaluated()) {96 return 0;97 } else {98#ifndef LIBC_MATH_HAS_NO_EXCEPT99 if (math_errhandling & MATH_ERREXCEPT)100 return set_except(excepts);101#endif // LIBC_MATH_HAS_NO_EXCEPT102 return 0;103 }104}105 106LIBC_INLINE static constexpr int107raise_except_if_required([[maybe_unused]] int excepts) {108 if (cpp::is_constant_evaluated()) {109 return 0;110 } else {111#ifndef LIBC_MATH_HAS_NO_EXCEPT112 if (math_errhandling & MATH_ERREXCEPT)113#ifdef LIBC_TARGET_ARCH_IS_X86_64114 return raise_except</*SKIP_X87_FPU*/ true>(excepts);115#else // !LIBC_TARGET_ARCH_IS_X86116 return raise_except(excepts);117#endif // LIBC_TARGET_ARCH_IS_X86118 119#endif // LIBC_MATH_HAS_NO_EXCEPT120 return 0;121 }122}123 124LIBC_INLINE static constexpr void125set_errno_if_required([[maybe_unused]] int err) {126 if (!cpp::is_constant_evaluated()) {127#ifndef LIBC_MATH_HAS_NO_ERRNO128 if (math_errhandling & MATH_ERRNO)129 libc_errno = err;130#endif // LIBC_MATH_HAS_NO_ERRNO131 }132}133 134} // namespace fputil135} // namespace LIBC_NAMESPACE_DECL136 137#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FENVIMPL_H138