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/i387/fenv.c,v 1.3 2007/01/05 07:15:26 das Exp $
29 #define __BSD_VISIBLE 1
32 #define __INITIAL_FPUCW_I386__ 0x127F
33 #define __INITIAL_NPXCW__ __INITIAL_FPUCW_I386__
35 const fenv_t __fe_dfl_env
= {
41 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }
45 extern inline int feclearexcept(int __excepts
);
46 extern inline int fegetexceptflag(fexcept_t
*__flagp
, int __excepts
);
49 fesetexceptflag(const fexcept_t
*flagp
, int excepts
)
55 env
.__status
&= ~excepts
;
56 env
.__status
|= *flagp
& excepts
;
62 mxcsr
|= *flagp
& excepts
;
70 feraiseexcept(int excepts
)
72 fexcept_t ex
= excepts
;
74 fesetexceptflag(&ex
, excepts
);
79 extern inline int fetestexcept(int __excepts
);
80 extern inline int fegetround(void);
81 extern inline int fesetround(int __round
);
84 fegetenv(fenv_t
*envp
)
90 * fnstenv masks all exceptions, so we need to restore
91 * the old control word to avoid this side effect.
93 __fldcw(envp
->__control
);
96 __set_mxcsr(*envp
, mxcsr
);
102 feholdexcept(fenv_t
*envp
)
110 __set_mxcsr(*envp
, mxcsr
);
111 mxcsr
&= ~FE_ALL_EXCEPT
;
112 mxcsr
|= FE_ALL_EXCEPT
<< _SSE_EMASK_SHIFT
;
118 extern inline int fesetenv(const fenv_t
*__envp
);
121 feupdateenv(const fenv_t
*envp
)
132 feraiseexcept((mxcsr
| status
) & FE_ALL_EXCEPT
);
137 __feenableexcept(int mask
)
139 uint32_t mxcsr
, omask
;
142 mask
&= FE_ALL_EXCEPT
;
148 omask
= ~(control
| mxcsr
>> _SSE_EMASK_SHIFT
) & FE_ALL_EXCEPT
;
152 mxcsr
&= ~(mask
<< _SSE_EMASK_SHIFT
);
159 __fedisableexcept(int mask
)
161 uint32_t mxcsr
, omask
;
164 mask
&= FE_ALL_EXCEPT
;
170 omask
= ~(control
| mxcsr
>> _SSE_EMASK_SHIFT
) & FE_ALL_EXCEPT
;
174 mxcsr
|= mask
<< _SSE_EMASK_SHIFT
;
180 AROS_MAKE_ASM_SYM(typeof(feenableexcept
), feenableexcept
, AROS_CSYM_FROM_ASM_NAME(feenableexcept
), AROS_CSYM_FROM_ASM_NAME(__feenableexcept
));
181 AROS_EXPORT_ASM_SYM(AROS_CSYM_FROM_ASM_NAME(feenableexcept
));
183 AROS_MAKE_ASM_SYM(typeof(fedisableexcept
), fedisableexcept
, AROS_CSYM_FROM_ASM_NAME(fedisableexcept
), AROS_CSYM_FROM_ASM_NAME(__fedisableexcept
));
184 AROS_EXPORT_ASM_SYM(AROS_CSYM_FROM_ASM_NAME(fedisableexcept
));