1+ /*-
2+ * Copyright (c) 2004-2011 David Schultz <das@FreeBSD.ORG>
3+ * All rights reserved.
4+ *
5+ * Redistribution and use in source and binary forms, with or without
6+ * modification, are permitted provided that the following conditions
7+ * are met:
8+ * 1. Redistributions of source code must retain the above copyright
9+ * notice, this list of conditions and the following disclaimer.
10+ * 2. Redistributions in binary form must reproduce the above copyright
11+ * notice, this list of conditions and the following disclaimer in the
12+ * documentation and/or other materials provided with the distribution.
13+ *
14+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24+ * SUCH DAMAGE.
25+ *
26+ * $FreeBSD$
27+ */
28+
29+ #ifndef _FENV_H_
30+ #error "This file is meant to be included only by <fenv.h>."
31+ #endif
32+
33+ /*
34+ * This file implements the functionality of <fenv.h> on platforms that
35+ * lack an FPU and use softfloat in libc for floating point. To use it,
36+ * you must write an <fenv.h> that provides the following:
37+ *
38+ * - a typedef for fenv_t, which may be an integer or struct type
39+ * - a typedef for fexcept_t (XXX This file assumes fexcept_t is a
40+ * simple integer type containing the exception mask.)
41+ * - definitions of FE_* constants for the five exceptions and four
42+ * rounding modes in IEEE 754, as described in fenv(3)
43+ * - a definition, and the corresponding external symbol, for FE_DFL_ENV
44+ * - a macro __set_env(env, flags, mask, rnd), which sets the given fenv_t
45+ * from the exception flags, mask, and rounding mode
46+ * - macros __env_flags(env), __env_mask(env), and __env_round(env), which
47+ * extract fields from an fenv_t
48+ * - a definition of __fenv_static
49+ *
50+ * If the architecture supports an optional FPU, it's recommended that you
51+ * define fenv_t and fexcept_t to match the hardware ABI. Otherwise, it
52+ * doesn't matter how you define them.
53+ */
54+
55+ extern int __softfloat_float_exception_flags ;
56+ extern int __softfloat_float_exception_mask ;
57+ extern int __softfloat_float_rounding_mode ;
58+ void __softfloat_float_raise (int );
59+
60+ __fenv_static inline int
61+ feclearexcept (int __excepts )
62+ {
63+
64+ __softfloat_float_exception_flags &= ~__excepts ;
65+ return (0 );
66+ }
67+
68+ __fenv_static inline int
69+ fegetexceptflag (fexcept_t * __flagp , int __excepts )
70+ {
71+
72+ * __flagp = __softfloat_float_exception_flags & __excepts ;
73+ return (0 );
74+ }
75+
76+ __fenv_static inline int
77+ fesetexceptflag (const fexcept_t * __flagp , int __excepts )
78+ {
79+
80+ __softfloat_float_exception_flags &= ~__excepts ;
81+ __softfloat_float_exception_flags |= * __flagp & __excepts ;
82+ return (0 );
83+ }
84+
85+ __fenv_static inline int
86+ feraiseexcept (int __excepts )
87+ {
88+
89+ __softfloat_float_raise (__excepts );
90+ return (0 );
91+ }
92+
93+ __fenv_static inline int
94+ fetestexcept (int __excepts )
95+ {
96+
97+ return (__softfloat_float_exception_flags & __excepts );
98+ }
99+
100+ __fenv_static inline int
101+ fegetround (void )
102+ {
103+
104+ return (__softfloat_float_rounding_mode );
105+ }
106+
107+ __fenv_static inline int
108+ fesetround (int __round )
109+ {
110+
111+ __softfloat_float_rounding_mode = __round ;
112+ return (0 );
113+ }
114+
115+ __fenv_static inline int
116+ fegetenv (fenv_t * __envp )
117+ {
118+
119+ __set_env (* __envp , __softfloat_float_exception_flags ,
120+ __softfloat_float_exception_mask , __softfloat_float_rounding_mode );
121+ return (0 );
122+ }
123+
124+ __fenv_static inline int
125+ feholdexcept (fenv_t * __envp )
126+ {
127+ fenv_t __env ;
128+
129+ fegetenv (__envp );
130+ __softfloat_float_exception_flags = 0 ;
131+ __softfloat_float_exception_mask = 0 ;
132+ return (0 );
133+ }
134+
135+ __fenv_static inline int
136+ fesetenv (const fenv_t * __envp )
137+ {
138+
139+ __softfloat_float_exception_flags = __env_flags (* __envp );
140+ __softfloat_float_exception_mask = __env_mask (* __envp );
141+ __softfloat_float_rounding_mode = __env_round (* __envp );
142+ return (0 );
143+ }
144+
145+ __fenv_static inline int
146+ feupdateenv (const fenv_t * __envp )
147+ {
148+ int __oflags = __softfloat_float_exception_flags ;
149+
150+ fesetenv (__envp );
151+ feraiseexcept (__oflags );
152+ return (0 );
153+ }
154+
155+ #if __BSD_VISIBLE
156+
157+ /* We currently provide no external definitions of the functions below. */
158+
159+ __fenv_static inline int
160+ feenableexcept (int __mask )
161+ {
162+ int __omask = __softfloat_float_exception_mask ;
163+
164+ __softfloat_float_exception_mask |= __mask ;
165+ return (__omask );
166+ }
167+
168+ __fenv_static inline int
169+ fedisableexcept (int __mask )
170+ {
171+ int __omask = __softfloat_float_exception_mask ;
172+
173+ __softfloat_float_exception_mask &= ~__mask ;
174+ return (__omask );
175+ }
176+
177+ __fenv_static inline int
178+ fegetexcept (void )
179+ {
180+
181+ return (__softfloat_float_exception_mask );
182+ }
183+
184+ #endif /* __BSD_VISIBLE */
0 commit comments