1 /*- 2 * Copyright (c) 2004 David Schultz <das (at) 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/arm/fenv.c,v 1.1 2004/06/06 10:03:59 das Exp $ 27 */ 28 29 #ifndef ANDROID_LEGACY_FENV_INLINES_ARM_H 30 #define ANDROID_LEGACY_FENV_INLINES_ARM_H 31 32 #include <fenv.h> 33 34 #if __ANDROID_API__ < __ANDROID_API_L__ && defined(__arm__) 35 36 __BEGIN_DECLS 37 38 #define FPSCR_ENABLE_SHIFT 8 39 #define FPSCR_ENABLE_MASK (FE_ALL_EXCEPT << FPSCR_ENABLE_SHIFT) 40 41 #define FPSCR_RMODE_SHIFT 22 42 43 static __inline int fegetenv(fenv_t* __envp) { 44 fenv_t _fpscr; 45 __asm__ __volatile__("vmrs %0,fpscr" : "=r" (_fpscr)); 46 *__envp = _fpscr; 47 return 0; 48 } 49 50 static __inline int fesetenv(const fenv_t* __envp) { 51 fenv_t _fpscr = *__envp; 52 __asm__ __volatile__("vmsr fpscr,%0" : :"ri" (_fpscr)); 53 return 0; 54 } 55 56 static __inline int feclearexcept(int __excepts) { 57 fexcept_t __fpscr; 58 fegetenv(&__fpscr); 59 __fpscr &= ~__excepts; 60 fesetenv(&__fpscr); 61 return 0; 62 } 63 64 static __inline int fegetexceptflag(fexcept_t* __flagp, int __excepts) { 65 fexcept_t __fpscr; 66 fegetenv(&__fpscr); 67 *__flagp = __fpscr & __excepts; 68 return 0; 69 } 70 71 static __inline int fesetexceptflag(const fexcept_t* __flagp, int __excepts) { 72 fexcept_t __fpscr; 73 fegetenv(&__fpscr); 74 __fpscr &= ~__excepts; 75 __fpscr |= *__flagp & __excepts; 76 fesetenv(&__fpscr); 77 return 0; 78 } 79 80 static __inline int feraiseexcept(int __excepts) { 81 fexcept_t __ex = __excepts; 82 fesetexceptflag(&__ex, __excepts); 83 return 0; 84 } 85 86 static __inline int fetestexcept(int __excepts) { 87 fexcept_t __fpscr; 88 fegetenv(&__fpscr); 89 return (__fpscr & __excepts); 90 } 91 92 static __inline int fegetround(void) { 93 fenv_t _fpscr; 94 fegetenv(&_fpscr); 95 return ((_fpscr >> FPSCR_RMODE_SHIFT) & 0x3); 96 } 97 98 static __inline int fesetround(int __round) { 99 fenv_t _fpscr; 100 fegetenv(&_fpscr); 101 _fpscr &= ~(0x3 << FPSCR_RMODE_SHIFT); 102 _fpscr |= (__round << FPSCR_RMODE_SHIFT); 103 fesetenv(&_fpscr); 104 return 0; 105 } 106 107 static __inline int feholdexcept(fenv_t* __envp) { 108 fenv_t __env; 109 fegetenv(&__env); 110 *__envp = __env; 111 __env &= ~(FE_ALL_EXCEPT | FPSCR_ENABLE_MASK); 112 fesetenv(&__env); 113 return 0; 114 } 115 116 static __inline int feupdateenv(const fenv_t* __envp) { 117 fexcept_t __fpscr; 118 fegetenv(&__fpscr); 119 fesetenv(__envp); 120 feraiseexcept(__fpscr & FE_ALL_EXCEPT); 121 return 0; 122 } 123 124 static __inline int feenableexcept(int __mask) { 125 fenv_t __old_fpscr, __new_fpscr; 126 fegetenv(&__old_fpscr); 127 __new_fpscr = __old_fpscr | (__mask & FE_ALL_EXCEPT) << FPSCR_ENABLE_SHIFT; 128 fesetenv(&__new_fpscr); 129 return ((__old_fpscr >> FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT); 130 } 131 132 static __inline int fedisableexcept(int __mask) { 133 fenv_t __old_fpscr, __new_fpscr; 134 fegetenv(&__old_fpscr); 135 __new_fpscr = __old_fpscr & ~((__mask & FE_ALL_EXCEPT) << FPSCR_ENABLE_SHIFT); 136 fesetenv(&__new_fpscr); 137 return ((__old_fpscr >> FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT); 138 } 139 140 static __inline int fegetexcept(void) { 141 fenv_t __fpscr; 142 fegetenv(&__fpscr); 143 return ((__fpscr & FPSCR_ENABLE_MASK) >> FPSCR_ENABLE_SHIFT); 144 } 145 146 #undef FPSCR_ENABLE_SHIFT 147 #undef FPSCR_ENABLE_MASK 148 #undef FPSCR_RMODE_SHIFT 149 150 __END_DECLS 151 152 #endif /* __ANDROID_API__ < __ANDROID_API_L__ && defined(__arm__) */ 153 154 #endif /* ANDROID_LEGACY_FENV_INLINES_ARM_H */ 155