• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-
2  * Copyright (c) 2004-2005 David Schultz <das@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.h,v 1.5 2005/03/16 19:03:45 das Exp $
27  */
28 
29 /*
30  * Rewritten for Android.
31  *
32  * The ARM FPSCR is described here:
33  * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344b/Chdfafia.html
34  */
35 
36 #ifndef _FENV_H_
37 #define _FENV_H_
38 
39 #include <machine/fenv.h>
40 #include <sys/types.h>
41 
42 __BEGIN_DECLS
43 
44 #define _FPSCR_ENABLE_SHIFT 8
45 #define _FPSCR_ENABLE_MASK (FE_ALL_EXCEPT << _FPSCR_ENABLE_SHIFT)
46 
47 #define _FPSCR_RMODE_SHIFT 22
48 
49 /* Default floating-point environment. */
50 extern const fenv_t __fe_dfl_env;
51 #define FE_DFL_ENV (&__fe_dfl_env)
52 
fegetenv(fenv_t * __envp)53 static __inline int fegetenv(fenv_t* __envp) {
54   fenv_t _fpscr;
55 #if !defined(__SOFTFP__)
56   #if !defined(__thumb__) || defined(__thumb2__)
57   __asm__ __volatile__("vmrs %0,fpscr" : "=r" (_fpscr));
58   #else
59    /* Switching from thumb1 to arm, do vmrs, then switch back */
60   __asm__ __volatile__(
61     ".balign 4           \n\t"
62     "mov     ip, pc      \n\t"
63     "bx      ip          \n\t"
64     ".arm                \n\t"
65     "vmrs    %0, fpscr   \n\t"
66     "add     ip, pc, #1  \n\t"
67     "bx      ip          \n\t"
68     ".thumb              \n\t"
69     : "=r" (_fpscr) : : "ip");
70   #endif
71 #else
72   _fpscr = 0;
73 #endif
74   *__envp = _fpscr;
75   return 0;
76 }
77 
fesetenv(const fenv_t * __envp)78 static __inline int fesetenv(const fenv_t* __envp) {
79   fenv_t _fpscr = *__envp;
80 #if !defined(__SOFTFP__)
81   #if !defined(__thumb__) || defined(__thumb2__)
82   __asm__ __volatile__("vmsr fpscr,%0" : :"ri" (_fpscr));
83   #else
84    /* Switching from thumb1 to arm, do vmsr, then switch back */
85   __asm__ __volatile__(
86     ".balign 4           \n\t"
87     "mov     ip, pc      \n\t"
88     "bx      ip          \n\t"
89     ".arm                \n\t"
90     "vmsr    fpscr, %0   \n\t"
91     "add     ip, pc, #1  \n\t"
92     "bx      ip          \n\t"
93     ".thumb              \n\t"
94     : : "ri" (_fpscr) : "ip");
95   #endif
96 #else
97   _fpscr = _fpscr;
98 #endif
99   return 0;
100 }
101 
feclearexcept(int __excepts)102 static __inline int feclearexcept(int __excepts) {
103   fexcept_t __fpscr;
104   fegetenv(&__fpscr);
105   __fpscr &= ~__excepts;
106   fesetenv(&__fpscr);
107   return 0;
108 }
109 
fegetexceptflag(fexcept_t * __flagp,int __excepts)110 static __inline int fegetexceptflag(fexcept_t* __flagp, int __excepts) {
111   fexcept_t __fpscr;
112   fegetenv(&__fpscr);
113   *__flagp = __fpscr & __excepts;
114   return 0;
115 }
116 
fesetexceptflag(const fexcept_t * __flagp,int __excepts)117 static __inline int fesetexceptflag(const fexcept_t* __flagp, int __excepts) {
118   fexcept_t __fpscr;
119   fegetenv(&__fpscr);
120   __fpscr &= ~__excepts;
121   __fpscr |= *__flagp & __excepts;
122   fesetenv(&__fpscr);
123   return 0;
124 }
125 
feraiseexcept(int __excepts)126 static __inline int feraiseexcept(int __excepts) {
127   fexcept_t __ex = __excepts;
128   fesetexceptflag(&__ex, __excepts);
129   return 0;
130 }
131 
fetestexcept(int __excepts)132 static __inline int fetestexcept(int __excepts) {
133   fexcept_t __fpscr;
134   fegetenv(&__fpscr);
135   return (__fpscr & __excepts);
136 }
137 
fegetround(void)138 static __inline int fegetround(void) {
139   fenv_t _fpscr;
140   fegetenv(&_fpscr);
141   return ((_fpscr >> _FPSCR_RMODE_SHIFT) & 0x3);
142 }
143 
fesetround(int __round)144 static __inline int fesetround(int __round) {
145   fenv_t _fpscr;
146   fegetenv(&_fpscr);
147   _fpscr &= ~(0x3 << _FPSCR_RMODE_SHIFT);
148   _fpscr |= (__round << _FPSCR_RMODE_SHIFT);
149   fesetenv(&_fpscr);
150   return 0;
151 }
152 
feholdexcept(fenv_t * __envp)153 static __inline int feholdexcept(fenv_t* __envp) {
154   fenv_t __env;
155   fegetenv(&__env);
156   *__envp = __env;
157   __env &= ~(FE_ALL_EXCEPT | _FPSCR_ENABLE_MASK);
158   fesetenv(&__env);
159   return 0;
160 }
161 
feupdateenv(const fenv_t * __envp)162 static __inline int feupdateenv(const fenv_t* __envp) {
163   fexcept_t __fpscr;
164   fegetenv(&__fpscr);
165   fesetenv(__envp);
166   feraiseexcept(__fpscr & FE_ALL_EXCEPT);
167   return 0;
168 }
169 
170 #if __BSD_VISIBLE
171 
feenableexcept(int __mask)172 static __inline int feenableexcept(int __mask) {
173   fenv_t __old_fpscr, __new_fpscr;
174   fegetenv(&__old_fpscr);
175   __new_fpscr = __old_fpscr | (__mask & FE_ALL_EXCEPT) << _FPSCR_ENABLE_SHIFT;
176   fesetenv(&__new_fpscr);
177   return ((__old_fpscr >> _FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT);
178 }
179 
fedisableexcept(int __mask)180 static __inline int fedisableexcept(int __mask) {
181   fenv_t __old_fpscr, __new_fpscr;
182   fegetenv(&__old_fpscr);
183   __new_fpscr = __old_fpscr & ~((__mask & FE_ALL_EXCEPT) << _FPSCR_ENABLE_SHIFT);
184   fesetenv(&__new_fpscr);
185   return ((__old_fpscr >> _FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT);
186 }
187 
fegetexcept(void)188 static __inline int fegetexcept(void) {
189   fenv_t __fpscr;
190   fegetenv(&__fpscr);
191   return ((__fpscr & _FPSCR_ENABLE_MASK) >> _FPSCR_ENABLE_SHIFT);
192 }
193 
194 #endif /* __BSD_VISIBLE */
195 
196 __END_DECLS
197 
198 #endif /* !_FENV_H_ */
199