2
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
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.
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
26
* $FreeBSD: src/lib/msun/amd64/fenv.h,v 1.5 2005/03/16 22:34:14 das Exp $
32
#include <sys/cdefs.h>
33
#include <sys/_types.h>
45
typedef __uint16_t fexcept_t;
48
#define FE_INVALID 0x01
49
#define FE_DENORMAL 0x02
50
#define FE_DIVBYZERO 0x04
51
#define FE_OVERFLOW 0x08
52
#define FE_UNDERFLOW 0x10
53
#define FE_INEXACT 0x20
54
#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
55
FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
58
#define FE_TONEAREST 0x0000
59
#define FE_DOWNWARD 0x0400
60
#define FE_UPWARD 0x0800
61
#define FE_TOWARDZERO 0x0c00
62
#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
63
FE_UPWARD | FE_TOWARDZERO)
66
* As compared to the x87 control word, the SSE unit's control word
67
* has the rounding control bits offset by 3 and the exception mask
70
#define _SSE_ROUND_SHIFT 3
71
#define _SSE_EMASK_SHIFT 7
75
/* Default floating-point environment */
76
extern const fenv_t __fe_dfl_env;
77
#define FE_DFL_ENV (&__fe_dfl_env)
79
#define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw))
80
#define __fldenv(__env) __asm __volatile("fldenv %0" : : "m" (__env))
81
#define __fnclex() __asm __volatile("fnclex")
82
#define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env)))
83
#define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw)))
84
#define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=am" (*(__sw)))
85
#define __fwait() __asm __volatile("fwait")
86
#define __ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr))
87
#define __stmxcsr(__csr) __asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
90
feclearexcept(int __excepts)
94
if (__excepts == FE_ALL_EXCEPT) {
97
__fnstenv(&__env.__x87);
98
__env.__x87.__status &= ~__excepts;
99
__fldenv(__env.__x87);
101
__stmxcsr(&__env.__mxcsr);
102
__env.__mxcsr &= ~__excepts;
103
__ldmxcsr(__env.__mxcsr);
108
fegetexceptflag(fexcept_t *__flagp, int __excepts)
110
int __mxcsr, __status;
114
*__flagp = (__mxcsr | __status) & __excepts;
118
int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
119
int feraiseexcept(int __excepts);
122
fetestexcept(int __excepts)
124
int __mxcsr, __status;
128
return ((__status | __mxcsr) & __excepts);
137
* We assume that the x87 and the SSE unit agree on the
138
* rounding mode. Reading the control word on the x87 turns
139
* out to be about 5 times faster than reading it on the SSE
140
* unit on an Opteron 244.
142
__fnstcw(&__control);
143
return (__control & _ROUND_MASK);
147
fesetround(int __round)
149
int __mxcsr, __control;
151
if (__round & ~_ROUND_MASK)
154
__fnstcw(&__control);
155
__control &= ~_ROUND_MASK;
156
__control |= __round;
160
__mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
161
__mxcsr |= __round << _SSE_ROUND_SHIFT;
167
int fegetenv(fenv_t *__envp);
168
int feholdexcept(fenv_t *__envp);
171
fesetenv(const fenv_t *__envp)
174
__fldenv(__envp->__x87);
175
__ldmxcsr(__envp->__mxcsr);
179
int feupdateenv(const fenv_t *__envp);
183
int feenableexcept(int __mask);
184
int fedisableexcept(int __mask);
192
* We assume that the masks for the x87 and the SSE unit are
195
__fnstcw(&__control);
196
return (~__control & FE_ALL_EXCEPT);
199
#endif /* __BSD_VISIBLE */
203
#endif /* !_FENV_H_ */