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