xref: /freebsd/contrib/llvm-project/libc/src/__support/FPUtil/FEnvImpl.h (revision bb722a7d0f1642bff6487f943ad0427799a6e5bf)
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 Andric LIBC_INLINE int clear_except(int) { return 0; }
45*bb722a7dSDimitry Andric 
test_except(int)46*bb722a7dSDimitry Andric LIBC_INLINE int test_except(int) { return 0; }
47*bb722a7dSDimitry Andric 
get_except()48*bb722a7dSDimitry Andric LIBC_INLINE int get_except() { return 0; }
49*bb722a7dSDimitry Andric 
set_except(int)50*bb722a7dSDimitry Andric LIBC_INLINE int set_except(int) { return 0; }
51*bb722a7dSDimitry Andric 
raise_except(int)52*bb722a7dSDimitry Andric LIBC_INLINE int raise_except(int) { return 0; }
53*bb722a7dSDimitry Andric 
enable_except(int)54*bb722a7dSDimitry Andric LIBC_INLINE int enable_except(int) { return 0; }
55*bb722a7dSDimitry Andric 
disable_except(int)56*bb722a7dSDimitry Andric LIBC_INLINE int disable_except(int) { return 0; }
57*bb722a7dSDimitry Andric 
get_round()58*bb722a7dSDimitry Andric LIBC_INLINE int get_round() { return FE_TONEAREST; }
59*bb722a7dSDimitry Andric 
set_round(int rounding_mode)60*bb722a7dSDimitry Andric LIBC_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 Andric LIBC_INLINE int get_env(fenv_t *) { return 0; }
65*bb722a7dSDimitry Andric 
set_env(const fenv_t *)66*bb722a7dSDimitry Andric LIBC_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 Andric LIBC_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 Andric LIBC_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 Andric LIBC_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 Andric LIBC_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