1*bb722a7dSDimitry Andric //===-- Floating point environment manipulation functions -------*- C++ -*-===// 2*bb722a7dSDimitry Andric // 3*bb722a7dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*bb722a7dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*bb722a7dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*bb722a7dSDimitry Andric // 7*bb722a7dSDimitry Andric //===----------------------------------------------------------------------===// 8*bb722a7dSDimitry Andric 9*bb722a7dSDimitry Andric #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FENVIMPL_H 10*bb722a7dSDimitry Andric #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FENVIMPL_H 11*bb722a7dSDimitry Andric 12*bb722a7dSDimitry Andric #include "hdr/fenv_macros.h" 13*bb722a7dSDimitry Andric #include "hdr/math_macros.h" 14*bb722a7dSDimitry Andric #include "hdr/types/fenv_t.h" 15*bb722a7dSDimitry Andric #include "src/__support/libc_errno.h" 16*bb722a7dSDimitry Andric #include "src/__support/macros/attributes.h" // LIBC_INLINE 17*bb722a7dSDimitry Andric #include "src/__support/macros/config.h" 18*bb722a7dSDimitry Andric #include "src/__support/macros/optimization.h" 19*bb722a7dSDimitry Andric #include "src/__support/macros/properties/architectures.h" 20*bb722a7dSDimitry Andric 21*bb722a7dSDimitry Andric #if defined(LIBC_TARGET_ARCH_IS_AARCH64) && defined(__ARM_FP) 22*bb722a7dSDimitry Andric #if defined(__APPLE__) 23*bb722a7dSDimitry Andric #include "aarch64/fenv_darwin_impl.h" 24*bb722a7dSDimitry Andric #else 25*bb722a7dSDimitry Andric #include "aarch64/FEnvImpl.h" 26*bb722a7dSDimitry Andric #endif 27*bb722a7dSDimitry Andric 28*bb722a7dSDimitry Andric // The extra !defined(APPLE) condition is to cause x86_64 MacOS builds to use 29*bb722a7dSDimitry Andric // the dummy implementations below. Once a proper x86_64 darwin fenv is set up, 30*bb722a7dSDimitry Andric // the apple condition here should be removed. 31*bb722a7dSDimitry Andric #elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__) 32*bb722a7dSDimitry Andric #include "x86_64/FEnvImpl.h" 33*bb722a7dSDimitry Andric #elif defined(LIBC_TARGET_ARCH_IS_ARM) && defined(__ARM_FP) 34*bb722a7dSDimitry Andric #include "arm/FEnvImpl.h" 35*bb722a7dSDimitry Andric #elif defined(LIBC_TARGET_ARCH_IS_ANY_RISCV) && defined(__riscv_flen) 36*bb722a7dSDimitry Andric #include "riscv/FEnvImpl.h" 37*bb722a7dSDimitry Andric #else 38*bb722a7dSDimitry Andric 39*bb722a7dSDimitry Andric namespace LIBC_NAMESPACE_DECL { 40*bb722a7dSDimitry Andric namespace fputil { 41*bb722a7dSDimitry Andric 42*bb722a7dSDimitry Andric // All dummy functions silently succeed. 43*bb722a7dSDimitry Andric clear_except(int)44*bb722a7dSDimitry AndricLIBC_INLINE int clear_except(int) { return 0; } 45*bb722a7dSDimitry Andric test_except(int)46*bb722a7dSDimitry AndricLIBC_INLINE int test_except(int) { return 0; } 47*bb722a7dSDimitry Andric get_except()48*bb722a7dSDimitry AndricLIBC_INLINE int get_except() { return 0; } 49*bb722a7dSDimitry Andric set_except(int)50*bb722a7dSDimitry AndricLIBC_INLINE int set_except(int) { return 0; } 51*bb722a7dSDimitry Andric raise_except(int)52*bb722a7dSDimitry AndricLIBC_INLINE int raise_except(int) { return 0; } 53*bb722a7dSDimitry Andric enable_except(int)54*bb722a7dSDimitry AndricLIBC_INLINE int enable_except(int) { return 0; } 55*bb722a7dSDimitry Andric disable_except(int)56*bb722a7dSDimitry AndricLIBC_INLINE int disable_except(int) { return 0; } 57*bb722a7dSDimitry Andric get_round()58*bb722a7dSDimitry AndricLIBC_INLINE int get_round() { return FE_TONEAREST; } 59*bb722a7dSDimitry Andric set_round(int rounding_mode)60*bb722a7dSDimitry AndricLIBC_INLINE int set_round(int rounding_mode) { 61*bb722a7dSDimitry Andric return (rounding_mode == FE_TONEAREST) ? 0 : 1; 62*bb722a7dSDimitry Andric } 63*bb722a7dSDimitry Andric get_env(fenv_t *)64*bb722a7dSDimitry AndricLIBC_INLINE int get_env(fenv_t *) { return 0; } 65*bb722a7dSDimitry Andric set_env(const fenv_t *)66*bb722a7dSDimitry AndricLIBC_INLINE int set_env(const fenv_t *) { return 0; } 67*bb722a7dSDimitry Andric 68*bb722a7dSDimitry Andric } // namespace fputil 69*bb722a7dSDimitry Andric } // namespace LIBC_NAMESPACE_DECL 70*bb722a7dSDimitry Andric #endif 71*bb722a7dSDimitry Andric 72*bb722a7dSDimitry Andric namespace LIBC_NAMESPACE_DECL { 73*bb722a7dSDimitry Andric namespace fputil { 74*bb722a7dSDimitry Andric clear_except_if_required(int excepts)75*bb722a7dSDimitry AndricLIBC_INLINE static int clear_except_if_required([[maybe_unused]] int excepts) { 76*bb722a7dSDimitry Andric #ifndef LIBC_MATH_HAS_NO_EXCEPT 77*bb722a7dSDimitry Andric if (math_errhandling & MATH_ERREXCEPT) 78*bb722a7dSDimitry Andric return clear_except(excepts); 79*bb722a7dSDimitry Andric #endif // LIBC_MATH_HAS_NO_EXCEPT 80*bb722a7dSDimitry Andric return 0; 81*bb722a7dSDimitry Andric } 82*bb722a7dSDimitry Andric set_except_if_required(int excepts)83*bb722a7dSDimitry AndricLIBC_INLINE static int set_except_if_required([[maybe_unused]] int excepts) { 84*bb722a7dSDimitry Andric #ifndef LIBC_MATH_HAS_NO_EXCEPT 85*bb722a7dSDimitry Andric if (math_errhandling & MATH_ERREXCEPT) 86*bb722a7dSDimitry Andric return set_except(excepts); 87*bb722a7dSDimitry Andric #endif // LIBC_MATH_HAS_NO_EXCEPT 88*bb722a7dSDimitry Andric return 0; 89*bb722a7dSDimitry Andric } 90*bb722a7dSDimitry Andric raise_except_if_required(int excepts)91*bb722a7dSDimitry AndricLIBC_INLINE static int raise_except_if_required([[maybe_unused]] int excepts) { 92*bb722a7dSDimitry Andric #ifndef LIBC_MATH_HAS_NO_EXCEPT 93*bb722a7dSDimitry Andric if (math_errhandling & MATH_ERREXCEPT) 94*bb722a7dSDimitry Andric #ifdef LIBC_TARGET_ARCH_IS_X86_64 95*bb722a7dSDimitry Andric return raise_except</*SKIP_X87_FPU*/ true>(excepts); 96*bb722a7dSDimitry Andric #else // !LIBC_TARGET_ARCH_IS_X86 97*bb722a7dSDimitry Andric return raise_except(excepts); 98*bb722a7dSDimitry Andric #endif // LIBC_TARGET_ARCH_IS_X86 99*bb722a7dSDimitry Andric 100*bb722a7dSDimitry Andric #endif // LIBC_MATH_HAS_NO_EXCEPT 101*bb722a7dSDimitry Andric return 0; 102*bb722a7dSDimitry Andric } 103*bb722a7dSDimitry Andric set_errno_if_required(int err)104*bb722a7dSDimitry AndricLIBC_INLINE static void set_errno_if_required([[maybe_unused]] int err) { 105*bb722a7dSDimitry Andric #ifndef LIBC_MATH_HAS_NO_ERRNO 106*bb722a7dSDimitry Andric if (math_errhandling & MATH_ERRNO) 107*bb722a7dSDimitry Andric libc_errno = err; 108*bb722a7dSDimitry Andric #endif // LIBC_MATH_HAS_NO_ERRNO 109*bb722a7dSDimitry Andric } 110*bb722a7dSDimitry Andric 111*bb722a7dSDimitry Andric } // namespace fputil 112*bb722a7dSDimitry Andric } // namespace LIBC_NAMESPACE_DECL 113*bb722a7dSDimitry Andric 114*bb722a7dSDimitry Andric #endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FENVIMPL_H 115