Moved to a more openbsd-like fenv.h
Factored out common declarations to include/fenv.h and pushed
the implementation to .c files.
Bug: 11050744
Change-Id: I446b13cc4bc599d328343a8d392b07de280f6304
diff --git a/libm/arm/fenv.c b/libm/arm/fenv.c
index 469f198..a0108e8 100644
--- a/libm/arm/fenv.c
+++ b/libm/arm/fenv.c
@@ -33,3 +33,106 @@
* this as a default environment.
*/
const fenv_t __fe_dfl_env = 0;
+
+int fegetenv(fenv_t* __envp) {
+ fenv_t _fpscr;
+ __asm__ __volatile__("vmrs %0,fpscr" : "=r" (_fpscr));
+ *__envp = _fpscr;
+ return 0;
+}
+
+int fesetenv(const fenv_t* __envp) {
+ fenv_t _fpscr = *__envp;
+ __asm__ __volatile__("vmsr fpscr,%0" : :"ri" (_fpscr));
+ return 0;
+}
+
+int feclearexcept(int __excepts) {
+ fexcept_t __fpscr;
+ fegetenv(&__fpscr);
+ __fpscr &= ~__excepts;
+ fesetenv(&__fpscr);
+ return 0;
+}
+
+int fegetexceptflag(fexcept_t* __flagp, int __excepts) {
+ fexcept_t __fpscr;
+ fegetenv(&__fpscr);
+ *__flagp = __fpscr & __excepts;
+ return 0;
+}
+
+int fesetexceptflag(const fexcept_t* __flagp, int __excepts) {
+ fexcept_t __fpscr;
+ fegetenv(&__fpscr);
+ __fpscr &= ~__excepts;
+ __fpscr |= *__flagp & __excepts;
+ fesetenv(&__fpscr);
+ return 0;
+}
+
+int feraiseexcept(int __excepts) {
+ fexcept_t __ex = __excepts;
+ fesetexceptflag(&__ex, __excepts);
+ return 0;
+}
+
+int fetestexcept(int __excepts) {
+ fexcept_t __fpscr;
+ fegetenv(&__fpscr);
+ return (__fpscr & __excepts);
+}
+
+int fegetround(void) {
+ fenv_t _fpscr;
+ fegetenv(&_fpscr);
+ return ((_fpscr >> _FPSCR_RMODE_SHIFT) & 0x3);
+}
+
+int fesetround(int __round) {
+ fenv_t _fpscr;
+ fegetenv(&_fpscr);
+ _fpscr &= ~(0x3 << _FPSCR_RMODE_SHIFT);
+ _fpscr |= (__round << _FPSCR_RMODE_SHIFT);
+ fesetenv(&_fpscr);
+ return 0;
+}
+
+int feholdexcept(fenv_t* __envp) {
+ fenv_t __env;
+ fegetenv(&__env);
+ *__envp = __env;
+ __env &= ~(FE_ALL_EXCEPT | _FPSCR_ENABLE_MASK);
+ fesetenv(&__env);
+ return 0;
+}
+
+int feupdateenv(const fenv_t* __envp) {
+ fexcept_t __fpscr;
+ fegetenv(&__fpscr);
+ fesetenv(__envp);
+ feraiseexcept(__fpscr & FE_ALL_EXCEPT);
+ return 0;
+}
+
+int feenableexcept(int __mask) {
+ fenv_t __old_fpscr, __new_fpscr;
+ fegetenv(&__old_fpscr);
+ __new_fpscr = __old_fpscr | (__mask & FE_ALL_EXCEPT) << _FPSCR_ENABLE_SHIFT;
+ fesetenv(&__new_fpscr);
+ return ((__old_fpscr >> _FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT);
+}
+
+int fedisableexcept(int __mask) {
+ fenv_t __old_fpscr, __new_fpscr;
+ fegetenv(&__old_fpscr);
+ __new_fpscr = __old_fpscr & ~((__mask & FE_ALL_EXCEPT) << _FPSCR_ENABLE_SHIFT);
+ fesetenv(&__new_fpscr);
+ return ((__old_fpscr >> _FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT);
+}
+
+int fegetexcept(void) {
+ fenv_t __fpscr;
+ fegetenv(&__fpscr);
+ return ((__fpscr & _FPSCR_ENABLE_MASK) >> _FPSCR_ENABLE_SHIFT);
+}