b0264d52e15c65caae636d94751acec82f7d6508
[qemu] / fpu / softfloat-native.h
1 /* Native implementation of soft float functions */
2 #include <math.h>
3 #if defined(_BSD) && !defined(__APPLE__)
4 #include <ieeefp.h>
5 #else
6 #if !defined(_PRESOLARIS10)
7 #include <fenv.h>
8 #endif
9 #endif
10
11 typedef float float32;
12 typedef double float64;
13 #ifdef FLOATX80
14 typedef long double floatx80;
15 #endif
16
17 typedef union {
18     float32 f;
19     uint32_t i;
20 } float32u;
21 typedef union {
22     float64 f;
23     uint64_t i;
24 } float64u;
25 #ifdef FLOATX80
26 typedef union {
27     floatx80 f;
28     struct {
29         uint64_t low;
30         uint16_t high;
31     } i;
32 } floatx80u;
33 #endif
34
35 /*----------------------------------------------------------------------------
36 | Software IEC/IEEE floating-point rounding mode.
37 *----------------------------------------------------------------------------*/
38 #if defined(_BSD) && !defined(__APPLE__)
39 enum {
40     float_round_nearest_even = FP_RN,
41     float_round_down         = FP_RM,
42     float_round_up           = FP_RP,
43     float_round_to_zero      = FP_RZ
44 };
45 #elif defined(__arm__)
46 enum {
47     float_round_nearest_even = 0,
48     float_round_down         = 1,
49     float_round_up           = 2,
50     float_round_to_zero      = 3
51 };
52 #else
53 enum {
54     float_round_nearest_even = FE_TONEAREST,
55     float_round_down         = FE_DOWNWARD,
56     float_round_up           = FE_UPWARD,
57     float_round_to_zero      = FE_TOWARDZERO
58 };
59 #endif
60
61 typedef struct float_status {
62     signed char float_rounding_mode;
63 #ifdef FLOATX80
64     signed char floatx80_rounding_precision;
65 #endif
66 } float_status;
67
68 void set_float_rounding_mode(int val STATUS_PARAM);
69 #ifdef FLOATX80
70 void set_floatx80_rounding_precision(int val STATUS_PARAM);
71 #endif
72
73 /*----------------------------------------------------------------------------
74 | Software IEC/IEEE integer-to-floating-point conversion routines.
75 *----------------------------------------------------------------------------*/
76 float32 int32_to_float32( int STATUS_PARAM);
77 float64 int32_to_float64( int STATUS_PARAM);
78 #ifdef FLOATX80
79 floatx80 int32_to_floatx80( int STATUS_PARAM);
80 #endif
81 #ifdef FLOAT128
82 float128 int32_to_float128( int STATUS_PARAM);
83 #endif
84 float32 int64_to_float32( int64_t STATUS_PARAM);
85 float64 int64_to_float64( int64_t STATUS_PARAM);
86 #ifdef FLOATX80
87 floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
88 #endif
89 #ifdef FLOAT128
90 float128 int64_to_float128( int64_t STATUS_PARAM);
91 #endif
92
93 /*----------------------------------------------------------------------------
94 | Software IEC/IEEE single-precision conversion routines.
95 *----------------------------------------------------------------------------*/
96 int float32_to_int32( float32  STATUS_PARAM);
97 int float32_to_int32_round_to_zero( float32  STATUS_PARAM);
98 int64_t float32_to_int64( float32  STATUS_PARAM);
99 int64_t float32_to_int64_round_to_zero( float32  STATUS_PARAM);
100 float64 float32_to_float64( float32  STATUS_PARAM);
101 #ifdef FLOATX80
102 floatx80 float32_to_floatx80( float32  STATUS_PARAM);
103 #endif
104 #ifdef FLOAT128
105 float128 float32_to_float128( float32  STATUS_PARAM);
106 #endif
107
108 /*----------------------------------------------------------------------------
109 | Software IEC/IEEE single-precision operations.
110 *----------------------------------------------------------------------------*/
111 float32 float32_round_to_int( float32  STATUS_PARAM);
112 INLINE float32 float32_add( float32 a, float32 b STATUS_PARAM)
113 {
114     return a + b;
115 }
116 INLINE float32 float32_sub( float32 a, float32 b STATUS_PARAM)
117 {
118     return a - b;
119 }
120 INLINE float32 float32_mul( float32 a, float32 b STATUS_PARAM)
121 {
122     return a * b;
123 }
124 INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
125 {
126     return a / b;
127 }
128 float32 float32_rem( float32, float32  STATUS_PARAM);
129 float32 float32_sqrt( float32  STATUS_PARAM);
130 INLINE char float32_eq( float32 a, float32 b STATUS_PARAM)
131 {
132     return a == b;
133 }
134 INLINE char float32_le( float32 a, float32 b STATUS_PARAM)
135 {
136     return a <= b;
137 }
138 INLINE char float32_lt( float32 a, float32 b STATUS_PARAM)
139 {
140     return a < b;
141 }
142 INLINE char float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
143 {
144     return a <= b && a >= b;
145 }
146 INLINE char float32_le_quiet( float32 a, float32 b STATUS_PARAM)
147 {
148     return islessequal(a, b);
149 }
150 INLINE char float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
151 {
152     return isless(a, b);
153 }
154 INLINE char float32_unordered( float32 a, float32 b STATUS_PARAM)
155 {
156     return isunordered(a, b);
157
158 }
159 char float32_compare( float32, float32 STATUS_PARAM );
160 char float32_compare_quiet( float32, float32 STATUS_PARAM );
161 char float32_is_signaling_nan( float32 );
162
163 INLINE float32 float32_abs(float32 a)
164 {
165     return fabsf(a);
166 }
167
168 INLINE float32 float32_chs(float32 a)
169 {
170     return -a;
171 }
172
173 /*----------------------------------------------------------------------------
174 | Software IEC/IEEE double-precision conversion routines.
175 *----------------------------------------------------------------------------*/
176 int float64_to_int32( float64 STATUS_PARAM );
177 int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
178 int64_t float64_to_int64( float64 STATUS_PARAM );
179 int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
180 float32 float64_to_float32( float64 STATUS_PARAM );
181 #ifdef FLOATX80
182 floatx80 float64_to_floatx80( float64 STATUS_PARAM );
183 #endif
184 #ifdef FLOAT128
185 float128 float64_to_float128( float64 STATUS_PARAM );
186 #endif
187
188 /*----------------------------------------------------------------------------
189 | Software IEC/IEEE double-precision operations.
190 *----------------------------------------------------------------------------*/
191 float64 float64_round_to_int( float64 STATUS_PARAM );
192 INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM)
193 {
194     return a + b;
195 }
196 INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM)
197 {
198     return a - b;
199 }
200 INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM)
201 {
202     return a * b;
203 }
204 INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
205 {
206     return a / b;
207 }
208 float64 float64_rem( float64, float64 STATUS_PARAM );
209 float64 float64_sqrt( float64 STATUS_PARAM );
210 INLINE char float64_eq( float64 a, float64 b STATUS_PARAM)
211 {
212     return a == b;
213 }
214 INLINE char float64_le( float64 a, float64 b STATUS_PARAM)
215 {
216     return a <= b;
217 }
218 INLINE char float64_lt( float64 a, float64 b STATUS_PARAM)
219 {
220     return a < b;
221 }
222 INLINE char float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
223 {
224     return a <= b && a >= b;
225 }
226 INLINE char float64_le_quiet( float64 a, float64 b STATUS_PARAM)
227 {
228     return islessequal(a, b);
229 }
230 INLINE char float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
231 {
232     return isless(a, b);
233
234 }
235 INLINE char float64_unordered( float64 a, float64 b STATUS_PARAM)
236 {
237     return isunordered(a, b);
238
239 }
240 char float64_compare( float64, float64 STATUS_PARAM );
241 char float64_compare_quiet( float64, float64 STATUS_PARAM );
242 char float64_is_signaling_nan( float64 );
243
244 INLINE float64 float64_abs(float64 a)
245 {
246     return fabs(a);
247 }
248
249 INLINE float64 float64_chs(float64 a)
250 {
251     return -a;
252 }
253
254 #ifdef FLOATX80
255
256 /*----------------------------------------------------------------------------
257 | Software IEC/IEEE extended double-precision conversion routines.
258 *----------------------------------------------------------------------------*/
259 int floatx80_to_int32( floatx80 STATUS_PARAM );
260 int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
261 int64_t floatx80_to_int64( floatx80 STATUS_PARAM);
262 int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM);
263 float32 floatx80_to_float32( floatx80 STATUS_PARAM );
264 float64 floatx80_to_float64( floatx80 STATUS_PARAM );
265 #ifdef FLOAT128
266 float128 floatx80_to_float128( floatx80 STATUS_PARAM );
267 #endif
268
269 /*----------------------------------------------------------------------------
270 | Software IEC/IEEE extended double-precision operations.
271 *----------------------------------------------------------------------------*/
272 floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
273 INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM)
274 {
275     return a + b;
276 }
277 INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM)
278 {
279     return a - b;
280 }
281 INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM)
282 {
283     return a * b;
284 }
285 INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
286 {
287     return a / b;
288 }
289 floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
290 floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
291 INLINE char floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
292 {
293     return a == b;
294 }
295 INLINE char floatx80_le( floatx80 a, floatx80 b STATUS_PARAM)
296 {
297     return a <= b;
298 }
299 INLINE char floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
300 {
301     return a < b;
302 }
303 INLINE char floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
304 {
305     return a <= b && a >= b;
306 }
307 INLINE char floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM)
308 {
309     return islessequal(a, b);
310 }
311 INLINE char floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
312 {
313     return isless(a, b);
314
315 }
316 INLINE char floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
317 {
318     return isunordered(a, b);
319
320 }
321 char floatx80_compare( floatx80, floatx80 STATUS_PARAM );
322 char floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
323 char floatx80_is_signaling_nan( floatx80 );
324
325 INLINE floatx80 floatx80_abs(floatx80 a)
326 {
327     return fabsl(a);
328 }
329
330 INLINE floatx80 floatx80_chs(floatx80 a)
331 {
332     return -a;
333 }
334 #endif