source: trunk/src/emx/include/fenv.h@ 2017

Last change on this file since 2017 was 2013, checked in by bird, 20 years ago

o The smallcnv stuff is gone, waste of space since we're not really into

static linking. Should've done this when switching to gdtoa.

o Ported the msun and some other math bits from current FreeBSD libc.

This mostly replaces the EMX math, except for some double long variants
and some EMX specific ones. This is a risky change, but it's needed
if we're gonna catch up on the C99 bits and make libstdc++ happy.
There are some new headers, complex.h and fenv.h being the importan ones.
float.h have gotten some updates while math.h is totally replaced.
More than 100 standard functions were added!
NOTE: msun is using MATH_ERREXCEPT (math_errhandling) and not

MATH_ERRNO for error reporting.

I really hope this is not gonna uncover more OS/2 387 mess.

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1/*-
2 * Copyright (c) 2004-2005 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: src/lib/msun/i387/fenv.h,v 1.4 2005/03/17 22:21:46 das Exp $
27 */
28
29#ifndef _FENV_H_
30#define _FENV_H_
31
32#include <sys/cdefs.h>
33#include <sys/_types.h>
34
35/*
36 * To preserve binary compatibility with FreeBSD 5.3, we pack the
37 * mxcsr into some reserved fields, rather than changing sizeof(fenv_t).
38 */
39typedef struct {
40 __uint16_t __control;
41 __uint16_t __mxcsr_hi;
42 __uint16_t __status;
43 __uint16_t __mxcsr_lo;
44 __uint32_t __tag;
45 char __other[16];
46} fenv_t;
47
48#define __get_mxcsr(env) (((env).__mxcsr_hi << 16) | \
49 ((env).__mxcsr_lo))
50#define __set_mxcsr(env, x) do { \
51 (env).__mxcsr_hi = (__uint32_t)(x) >> 16; \
52 (env).__mxcsr_lo = (__uint16_t)(x); \
53} while (0)
54
55typedef __uint16_t fexcept_t;
56
57/* Exception flags */
58#define FE_INVALID 0x01
59#define FE_DENORMAL 0x02
60#define FE_DIVBYZERO 0x04
61#define FE_OVERFLOW 0x08
62#define FE_UNDERFLOW 0x10
63#define FE_INEXACT 0x20
64#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
65 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
66
67/* Rounding modes */
68#define FE_TONEAREST 0x0000
69#define FE_DOWNWARD 0x0400
70#define FE_UPWARD 0x0800
71#define FE_TOWARDZERO 0x0c00
72#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
73 FE_UPWARD | FE_TOWARDZERO)
74
75/*
76 * As compared to the x87 control word, the SSE unit's control word
77 * has the rounding control bits offset by 3 and the exception mask
78 * bits offset by 7.
79 */
80#define _SSE_ROUND_SHIFT 3
81#define _SSE_EMASK_SHIFT 7
82
83/* After testing for SSE support once, we cache the result in __has_sse. */
84enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK };
85extern enum __sse_support __has_sse;
86int __test_sse(void);
87#ifdef __SSE__
88#define __HAS_SSE() 1
89#else
90#define __HAS_SSE() (__has_sse == __SSE_YES || \
91 (__has_sse == __SSE_UNK && __test_sse()))
92#endif
93
94__BEGIN_DECLS
95
96/* Default floating-point environment */
97extern const fenv_t __fe_dfl_env;
98#define FE_DFL_ENV (&__fe_dfl_env)
99
100#define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw))
101#define __fldenv(__env) __asm __volatile("fldenv %0" : : "m" (__env))
102#define __fnclex() __asm __volatile("fnclex")
103#define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env)))
104#define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw)))
105#define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=am" (*(__sw)))
106#define __fwait() __asm __volatile("fwait")
107#define __ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr))
108#define __stmxcsr(__csr) __asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
109
110static __inline int
111feclearexcept(int __excepts)
112{
113 fenv_t __env;
114 int __mxcsr;
115
116 if (__excepts == FE_ALL_EXCEPT) {
117 __fnclex();
118 } else {
119 __fnstenv(&__env);
120 __env.__status &= ~__excepts;
121 __fldenv(__env);
122 }
123 if (__HAS_SSE()) {
124 __stmxcsr(&__mxcsr);
125 __mxcsr &= ~__excepts;
126 __ldmxcsr(__mxcsr);
127 }
128 return (0);
129}
130
131static __inline int
132fegetexceptflag(fexcept_t *__flagp, int __excepts)
133{
134 int __mxcsr, __status;
135
136 __fnstsw(&__status);
137 if (__HAS_SSE())
138 __stmxcsr(&__mxcsr);
139 else
140 __mxcsr = 0;
141 *__flagp = (__mxcsr | __status) & __excepts;
142 return (0);
143}
144
145int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
146int feraiseexcept(int __excepts);
147
148static __inline int
149fetestexcept(int __excepts)
150{
151 int __mxcsr, __status;
152
153 __fnstsw(&__status);
154 if (__HAS_SSE())
155 __stmxcsr(&__mxcsr);
156 else
157 __mxcsr = 0;
158 return ((__status | __mxcsr) & __excepts);
159}
160
161static __inline int
162fegetround(void)
163{
164 int __control;
165
166 /*
167 * We assume that the x87 and the SSE unit agree on the
168 * rounding mode. Reading the control word on the x87 turns
169 * out to be about 5 times faster than reading it on the SSE
170 * unit on an Opteron 244.
171 */
172 __fnstcw(&__control);
173 return (__control & _ROUND_MASK);
174}
175
176static __inline int
177fesetround(int __round)
178{
179 int __mxcsr, __control;
180
181 if (__round & ~_ROUND_MASK)
182 return (-1);
183
184 __fnstcw(&__control);
185 __control &= ~_ROUND_MASK;
186 __control |= __round;
187 __fldcw(__control);
188
189 if (__HAS_SSE()) {
190 __stmxcsr(&__mxcsr);
191 __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
192 __mxcsr |= __round << _SSE_ROUND_SHIFT;
193 __ldmxcsr(__mxcsr);
194 }
195
196 return (0);
197}
198
199int fegetenv(fenv_t *__envp);
200int feholdexcept(fenv_t *__envp);
201
202static __inline int
203fesetenv(const fenv_t *__envp)
204{
205 fenv_t __env = *__envp;
206 int __mxcsr;
207
208 __mxcsr = __get_mxcsr(__env);
209 __set_mxcsr(__env, 0xffffffff);
210 __fldenv(__env);
211 if (__HAS_SSE())
212 __ldmxcsr(__mxcsr);
213 return (0);
214}
215
216int feupdateenv(const fenv_t *__envp);
217
218#if __BSD_VISIBLE
219
220int feenableexcept(int __mask);
221int fedisableexcept(int __mask);
222
223static __inline int
224fegetexcept(void)
225{
226 int __control;
227
228 /*
229 * We assume that the masks for the x87 and the SSE unit are
230 * the same.
231 */
232 __fnstcw(&__control);
233 return (~__control & FE_ALL_EXCEPT);
234}
235
236#endif /* __BSD_VISIBLE */
237
238__END_DECLS
239
240#endif /* !_FENV_H_ */
Note: See TracBrowser for help on using the repository browser.