• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <portability.h>
18 #include <sys/types.h>
19 #include <fenv.h>
20 #include <fenv_portable.h>
21 
mips64_change_except(int flags)22 static inline int mips64_change_except(int flags) {
23   int mips64flags = 0;
24   int exception = flags & FE_ALL_EXCEPT_PORTABLE;
25 
26   // exception flags
27   if (exception & FE_INVALID_PORTABLE)
28       mips64flags |= FE_INVALID;
29   if (exception & FE_DIVBYZERO_PORTABLE)
30       mips64flags |= FE_DIVBYZERO;
31   if (exception & FE_OVERFLOW_PORTABLE)
32       mips64flags |= FE_OVERFLOW;
33   if (exception & FE_UNDERFLOW_PORTABLE)
34       mips64flags |= FE_UNDERFLOW;
35   if (exception & FE_INEXACT_PORTABLE)
36       mips64flags |= FE_INEXACT;
37 
38   return mips64flags;
39 }
40 
mips64_change_rounding(int flags)41 static inline int mips64_change_rounding(int flags) {
42   int mips64flags = 0;
43   int rounding = flags & 0x03;
44 
45   // rounding flags
46   switch(rounding)
47   {
48     case FE_TONEAREST_PORTABLE:
49       mips64flags = FE_TONEAREST;
50       break;
51     case FE_DOWNWARD_PORTABLE:
52       mips64flags = FE_DOWNWARD;
53       break;
54     case FE_UPWARD_PORTABLE:
55       mips64flags = FE_UPWARD;
56       break;
57     case FE_TOWARDZERO_PORTABLE:
58       mips64flags = FE_TOWARDZERO;
59       break;
60   }
61   return mips64flags;
62 }
63 
mips64_get_except(int mips64flags)64 static inline int mips64_get_except(int mips64flags) {
65   int flags = 0;
66   int exception = mips64flags & FE_ALL_EXCEPT;
67 
68   // exception flags
69   if (exception & FE_INVALID)
70       flags |= FE_INVALID_PORTABLE;
71   if (exception & FE_DIVBYZERO)
72       flags |= FE_DIVBYZERO_PORTABLE;
73   if (exception & FE_OVERFLOW)
74       flags |= FE_OVERFLOW_PORTABLE;
75   if (exception & FE_UNDERFLOW)
76       flags |= FE_UNDERFLOW_PORTABLE;
77   if (exception & FE_INEXACT)
78       flags |= FE_INEXACT_PORTABLE;
79   return flags;
80 }
81 
mips64_get_rounding(int mips64flags)82 static inline int mips64_get_rounding(int mips64flags) {
83   int flags = 0;
84   int rounding = mips64flags & _FCSR_RMASK;
85 
86   // rounding flags
87   switch(rounding)
88   {
89     case FE_TONEAREST:
90       flags = FE_TONEAREST_PORTABLE;
91       break;
92     case FE_DOWNWARD:
93       flags = FE_DOWNWARD_PORTABLE;
94       break;
95     case FE_UPWARD:
96       flags = FE_UPWARD_PORTABLE;
97       break;
98     case FE_TOWARDZERO:
99       flags = FE_TOWARDZERO_PORTABLE;
100       break;
101   }
102   return flags;
103 }
104 
105 
WRAP(feclearexcept)106 int WRAP(feclearexcept)(int flag) {
107   return REAL(feclearexcept)(mips64_change_except(flag));
108 }
109 
WRAP(fegetexceptflag)110 int WRAP(fegetexceptflag)(fexcept_t_portable *obj, int flag) {
111   int ret = REAL(fegetexceptflag)((fexcept_t*)obj, mips64_change_except(flag));
112   *obj = (fexcept_t_portable) mips64_get_except(*obj);
113   return ret;
114 }
115 
WRAP(feraiseexcept)116 int WRAP(feraiseexcept)(int flag) {
117   return REAL(feraiseexcept)(mips64_change_except(flag));
118 }
119 
WRAP(fesetexceptflag)120 int WRAP(fesetexceptflag)(const fexcept_t_portable *obj, int flag) {
121   const fexcept_t mips64obj = mips64_change_except(*obj);
122   int mips64flag = mips64_change_except(flag);
123   return REAL(fesetexceptflag)(&mips64obj, mips64flag);
124 }
125 
WRAP(fetestexcept)126 int WRAP(fetestexcept)(int flag) {
127   int ret = REAL(fetestexcept)(mips64_change_except(flag));
128   return mips64_get_except(ret);
129 }
130 
WRAP(fegetround)131 int WRAP(fegetround)(void) {
132   int round = REAL(fegetround)();
133   return mips64_get_rounding(round);
134 }
135 
WRAP(fesetround)136 int WRAP(fesetround)(int round) {
137   return REAL(fesetround)(mips64_change_rounding(round));
138 }
139 
WRAP(fegetenv)140 int WRAP(fegetenv)(fenv_t_portable *obj) {
141   return REAL(fegetenv)((fenv_t*)obj);
142 }
143 
WRAP(feholdexcept)144 int WRAP(feholdexcept)(fenv_t_portable *obj) {
145   return REAL(feholdexcept)((fenv_t*)obj);
146 }
147 
WRAP(fesetenv)148 int WRAP(fesetenv)(const fenv_t_portable *obj) {
149   return REAL(fesetenv)((const fenv_t*)obj);
150 }
151 
WRAP(feupdateenv)152 int WRAP(feupdateenv)(const fenv_t_portable *obj) {
153   return REAL(feupdateenv)((const fenv_t*)obj);
154 }
155 
WRAP(fegetexcept)156 int WRAP(fegetexcept)(void) {
157   int flag = REAL(fegetexcept)();
158   return mips64_get_except(flag);
159 }
160 
161