fenv.h

Go to the documentation of this file.
00001 /*--------------------------------------------------------------------
00002  *© Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
00003  *--------------------------------------------------------------------
00004 */
00005 /*-
00006  * Copyright (c) 2004-2005 David Schultz <[email protected]>
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
00019  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00022  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00023  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00024  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00025  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00026  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00027  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * $FreeBSD: src/lib/msun/arm/fenv.h,v 1.5 2005/03/16 19:03:45 das Exp $
00031  */
00032 
00033 #ifndef _FENV_H_
00034 #define _FENV_H_
00035 
00036 #if (defined(__SYMBIAN32__) && !defined(SYMBIAN))
00037 #define SYMBIAN
00038 #endif
00039 
00040 #include <sys/_types.h>
00041 
00042 #ifdef __WINSCW__
00043 /*to supress warnings 'arguments not used in function' 
00044 This warnings crop up wherever fevn.h is included. So
00045 it is desirable to supress it here. The warning arises as a
00046 fact that these arguments are used within macros which get
00047 get replaced at the time of pre-processing and thus the 
00048 compiler(s)warning 'argument/variable is not used in function*/
00049 #pragma warn_unusedarg off
00050 //__WINSCW__
00051 #endif
00052 
00053 typedef __uint32_t      fenv_t;
00054 typedef __uint32_t      fexcept_t;
00055 
00056 /* Exception flags */
00057 #define FE_INVALID      0x0001
00058 #define FE_DIVBYZERO    0x0002
00059 #define FE_OVERFLOW     0x0004
00060 #define FE_UNDERFLOW    0x0008
00061 #define FE_INEXACT      0x0010
00062 #define FE_ALL_EXCEPT   (FE_DIVBYZERO | FE_INEXACT | \
00063                          FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
00064 
00065 /* Rounding modes */
00066 #define FE_TONEAREST    0x0000
00067 #define FE_TOWARDZERO   0x0001
00068 #define FE_UPWARD       0x0002
00069 #define FE_DOWNWARD     0x0003
00070 #define _ROUND_MASK     (FE_TONEAREST | FE_DOWNWARD | \
00071                          FE_UPWARD | FE_TOWARDZERO)
00072 __BEGIN_DECLS
00073 
00074 /* Default floating-point environment */
00075 extern const fenv_t     __fe_dfl_env;
00076 #define FE_DFL_ENV      (&__fe_dfl_env)
00077 
00078 /* We need to be able to map status flag positions to mask flag positions */
00079 #define _FPUSW_SHIFT    16
00080 #define _ENABLE_MASK    (FE_ALL_EXCEPT << _FPUSW_SHIFT)
00081 
00082 #ifdef  ARM_HARD_FLOAT
00083 #define __rfs(__fpsr)   __asm __volatile("rfs %0" : "=r" (*(__fpsr)))
00084 #define __wfs(__fpsr)   __asm __volatile("wfs %0" : : "r" (__fpsr))
00085 #else
00086 #define __rfs(__fpsr)
00087 #define __wfs(__fpsr)
00088 #endif
00089 
00090 static __inline int
00091 feclearexcept(int __excepts)
00092 {
00093         #ifdef __SYMBIAN32__
00094         fexcept_t __fpsr = 0;
00095         #else
00096         fexcept_t __fpsr ;
00097         //__SYMBIAN32__
00098 #endif
00099 
00100         __rfs(&__fpsr);
00101         __fpsr &= ~__excepts;
00102         __wfs(__fpsr);
00103         return (0);
00104 }
00105 
00106 static __inline int
00107 fegetexceptflag(fexcept_t *__flagp, int __excepts)
00108 {
00109         #ifdef __SYMBIAN32__
00110         fexcept_t __fpsr = 0;
00111         #else
00112         fexcept_t __fpsr ;
00113         //__SYMBIAN32__
00114 #endif
00115 
00116         __rfs(&__fpsr);
00117         *__flagp = __fpsr & __excepts;
00118         return (0);
00119 }
00120 
00121 static __inline int
00122 fesetexceptflag(const fexcept_t *__flagp, int __excepts)
00123 {
00124         #ifdef __SYMBIAN32__
00125         fexcept_t __fpsr = 0;
00126         #else
00127         fexcept_t __fpsr ;
00128         //__SYMBIAN32__
00129 #endif
00130 
00131         __rfs(&__fpsr);
00132         __fpsr &= ~__excepts;
00133         __fpsr |= *__flagp & __excepts;
00134         __wfs(__fpsr);
00135         return (0);
00136 }
00137 
00138 static __inline int
00139 feraiseexcept(int __excepts)
00140 {
00141         fexcept_t __ex = __excepts;
00142 
00143         fesetexceptflag(&__ex, __excepts);      /* XXX */
00144         return (0);
00145 }
00146 
00147 static __inline int
00148 fetestexcept(int __excepts)
00149 {
00150         #ifdef __SYMBIAN32__
00151         fexcept_t __fpsr = 0;
00152         #else
00153         fexcept_t __fpsr ;
00154         //__SYMBIAN32__
00155 #endif
00156 
00157         __rfs(&__fpsr);
00158         return (__fpsr & __excepts);
00159 }
00160 
00161 static __inline int
00162 fegetround(void)
00163 {
00164 
00165         /*
00166          * Apparently, the rounding mode is specified as part of the
00167          * instruction format on ARM, so the dynamic rounding mode is
00168          * indeterminate.  Some FPUs may differ.
00169          */
00170         return (-1);
00171 }
00172 
00173 static __inline int
00174 fesetround(int __round)
00175 {
00176 
00177         return (-1);
00178 }
00179 
00180 static __inline int
00181 fegetenv(fenv_t *__envp)
00182 {
00183 
00184         __rfs(__envp);
00185         return (0);
00186 }
00187 
00188 static __inline int
00189 feholdexcept(fenv_t *__envp)
00190 {
00191         #ifdef __SYMBIAN32__
00192         fenv_t __env = 0;
00193         #else
00194         fenv_t __env ;
00195         //__SYMBIAN32__
00196 #endif
00197 
00198         __rfs(&__env);
00199         *__envp = __env;
00200         __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
00201         __wfs(__env);
00202         return (0);
00203 }
00204 
00205 static __inline int
00206 fesetenv(const fenv_t *__envp)
00207 {
00208 
00209         __wfs(*__envp);
00210         return (0);
00211 }
00212 
00213 static __inline int
00214 feupdateenv(const fenv_t *__envp)
00215 {
00216         #ifdef __SYMBIAN32__
00217         fexcept_t __fpsr = 0;
00218         #else
00219         fexcept_t __fpsr ;
00220         //__SYMBIAN32__
00221 #endif
00222 
00223         __rfs(&__fpsr);
00224         __wfs(*__envp);
00225         feraiseexcept(__fpsr & FE_ALL_EXCEPT);
00226         return (0);
00227 }
00228 
00229 #if __BSD_VISIBLE
00230 
00231 static __inline int
00232 feenableexcept(int __mask)
00233 {
00234         #ifdef __SYMBIAN32__
00235         fenv_t __old_fpsr = 0, __new_fpsr=  0;
00236         #else
00237         fenv_t __old_fpsr, __new_fpsr;
00238         //__SYMBIAN32__
00239 #endif
00240 
00241         __rfs(&__old_fpsr);
00242         __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT;
00243         __wfs(__new_fpsr);
00244         return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
00245 }
00246 
00247 static __inline int
00248 fedisableexcept(int __mask)
00249 {
00250 
00251         #ifdef __SYMBIAN32__
00252         fenv_t __old_fpsr =0, __new_fpsr =0;
00253         #else
00254         fenv_t __old_fpsr, __new_fpsr;
00255         //__SYMBIAN32__
00256 #endif
00257         
00258         __rfs(&__old_fpsr);
00259         __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
00260         __wfs(__new_fpsr);
00261         return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
00262 }
00263 
00264 static __inline int
00265 fegetexcept(void)
00266 {
00267         #ifdef __SYMBIAN32__
00268         fexcept_t __fpsr = 0;
00269         #else
00270         fexcept_t __fpsr ;
00271         //__SYMBIAN32__
00272 #endif
00273 
00274         __rfs(&__fpsr);
00275         return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT);
00276 }
00277 
00278 #endif /* __BSD_VISIBLE */
00279 
00280 __END_DECLS
00281 
00282 #endif  /* !_FENV_H_ */

Copyright © Nokia Corporation 2001-2008
Back to top