1:
2:
3: #include "softfloat.h"
4: #include <math.h>
5:
6: void set_float_rounding_mode(int val STATUS_PARAM)
7: {
8: STATUS(float_rounding_mode) = val;
9: #if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
10: fpsetround(val);
11: #elif defined(__arm__)
12:
13: #else
14: fesetround(val);
15: #endif
16: }
17:
18: #ifdef FLOATX80
19: void set_floatx80_rounding_precision(int val STATUS_PARAM)
20: {
21: STATUS(floatx80_rounding_precision) = val;
22: }
23: #endif
24:
25: #if defined(_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
26: #define lrint(d) ((int32_t)rint(d))
27: #define llrint(d) ((int64_t)rint(d))
28: #define lrintf(f) ((int32_t)rint(f))
29: #define llrintf(f) ((int64_t)rint(f))
30: #define sqrtf(f) ((float)sqrt(f))
31: #define remainderf(fa, fb) ((float)remainder(fa, fb))
32: #define rintf(f) ((float)rint(f))
33: #if !defined(__sparc__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
34: extern long double rintl(long double);
35: extern long double scalbnl(long double, int);
36:
37: long long
38: llrintl(long double x) {
39: return ((long long) rintl(x));
40: }
41:
42: long
43: lrintl(long double x) {
44: return ((long) rintl(x));
45: }
46:
47: long double
48: ldexpl(long double x, int n) {
49: return (scalbnl(x, n));
50: }
51: #endif
52: #endif
53:
54: #if defined(__powerpc__)
55:
56:
57: double qemu_rint(double x)
58: {
59: double y = 4503599627370496.0;
60: if (fabs(x) >= y)
61: return x;
62: if (x < 0)
63: y = -y;
64: y = (x + y) - y;
65: if (y == 0.0)
66: y = copysign(y, x);
67: return y;
68: }
69:
70: #define rint qemu_rint
71: #endif
72:
73:
74:
75:
76: float32 int32_to_float32(int v STATUS_PARAM)
77: {
78: return (float32)v;
79: }
80:
81: float32 uint32_to_float32(unsigned int v STATUS_PARAM)
82: {
83: return (float32)v;
84: }
85:
86: float64 int32_to_float64(int v STATUS_PARAM)
87: {
88: return (float64)v;
89: }
90:
91: float64 uint32_to_float64(unsigned int v STATUS_PARAM)
92: {
93: return (float64)v;
94: }
95:
96: #ifdef FLOATX80
97: floatx80 int32_to_floatx80(int v STATUS_PARAM)
98: {
99: return (floatx80)v;
100: }
101: #endif
102: float32 int64_to_float32( int64_t v STATUS_PARAM)
103: {
104: return (float32)v;
105: }
106: float32 uint64_to_float32( uint64_t v STATUS_PARAM)
107: {
108: return (float32)v;
109: }
110: float64 int64_to_float64( int64_t v STATUS_PARAM)
111: {
112: return (float64)v;
113: }
114: float64 uint64_to_float64( uint64_t v STATUS_PARAM)
115: {
116: return (float64)v;
117: }
118: #ifdef FLOATX80
119: floatx80 int64_to_floatx80( int64_t v STATUS_PARAM)
120: {
121: return (floatx80)v;
122: }
123: #endif
124:
125:
126: #if HOST_LONG_BITS == 32
127: static inline int long_to_int32(long a)
128: {
129: return a;
130: }
131: #else
132: static inline int long_to_int32(long a)
133: {
134: if (a != (int32_t)a)
135: a = 0x80000000;
136: return a;
137: }
138: #endif
139:
140:
141:
142:
143: int float32_to_int32( float32 a STATUS_PARAM)
144: {
145: return long_to_int32(lrintf(a));
146: }
147: int float32_to_int32_round_to_zero( float32 a STATUS_PARAM)
148: {
149: return (int)a;
150: }
151: int64_t float32_to_int64( float32 a STATUS_PARAM)
152: {
153: return llrintf(a);
154: }
155:
156: int64_t float32_to_int64_round_to_zero( float32 a STATUS_PARAM)
157: {
158: return (int64_t)a;
159: }
160:
161: float64 float32_to_float64( float32 a STATUS_PARAM)
162: {
163: return a;
164: }
165: #ifdef FLOATX80
166: floatx80 float32_to_floatx80( float32 a STATUS_PARAM)
167: {
168: return a;
169: }
170: #endif
171:
172: unsigned int float32_to_uint32( float32 a STATUS_PARAM)
173: {
174: int64_t v;
175: unsigned int res;
176:
177: v = llrintf(a);
178: if (v < 0) {
179: res = 0;
180: } else if (v > 0xffffffff) {
181: res = 0xffffffff;
182: } else {
183: res = v;
184: }
185: return res;
186: }
187: unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM)
188: {
189: int64_t v;
190: unsigned int res;
191:
192: v = (int64_t)a;
193: if (v < 0) {
194: res = 0;
195: } else if (v > 0xffffffff) {
196: res = 0xffffffff;
197: } else {
198: res = v;
199: }
200: return res;
201: }
202:
203:
204:
205:
206: float32 float32_round_to_int( float32 a STATUS_PARAM)
207: {
208: return rintf(a);
209: }
210:
211: float32 float32_rem( float32 a, float32 b STATUS_PARAM)
212: {
213: return remainderf(a, b);
214: }
215:
216: float32 float32_sqrt( float32 a STATUS_PARAM)
217: {
218: return sqrtf(a);
219: }
220: int float32_compare( float32 a, float32 b STATUS_PARAM )
221: {
222: if (a < b) {
223: return -1;
224: } else if (a == b) {
225: return 0;
226: } else if (a > b) {
227: return 1;
228: } else {
229: return 2;
230: }
231: }
232: int float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
233: {
234: if (isless(a, b)) {
235: return -1;
236: } else if (a == b) {
237: return 0;
238: } else if (isgreater(a, b)) {
239: return 1;
240: } else {
241: return 2;
242: }
243: }
244: int float32_is_signaling_nan( float32 a1)
245: {
246: float32u u;
247: uint32_t a;
248: u.f = a1;
249: a = u.i;
250: return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
251: }
252:
253:
254:
255:
256: int float64_to_int32( float64 a STATUS_PARAM)
257: {
258: return long_to_int32(lrint(a));
259: }
260: int float64_to_int32_round_to_zero( float64 a STATUS_PARAM)
261: {
262: return (int)a;
263: }
264: int64_t float64_to_int64( float64 a STATUS_PARAM)
265: {
266: return llrint(a);
267: }
268: int64_t float64_to_int64_round_to_zero( float64 a STATUS_PARAM)
269: {
270: return (int64_t)a;
271: }
272: float32 float64_to_float32( float64 a STATUS_PARAM)
273: {
274: return a;
275: }
276: #ifdef FLOATX80
277: floatx80 float64_to_floatx80( float64 a STATUS_PARAM)
278: {
279: return a;
280: }
281: #endif
282: #ifdef FLOAT128
283: float128 float64_to_float128( float64 a STATUS_PARAM)
284: {
285: return a;
286: }
287: #endif
288:
289: unsigned int float64_to_uint32( float64 a STATUS_PARAM)
290: {
291: int64_t v;
292: unsigned int res;
293:
294: v = llrint(a);
295: if (v < 0) {
296: res = 0;
297: } else if (v > 0xffffffff) {
298: res = 0xffffffff;
299: } else {
300: res = v;
301: }
302: return res;
303: }
304: unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM)
305: {
306: int64_t v;
307: unsigned int res;
308:
309: v = (int64_t)a;
310: if (v < 0) {
311: res = 0;
312: } else if (v > 0xffffffff) {
313: res = 0xffffffff;
314: } else {
315: res = v;
316: }
317: return res;
318: }
319: uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
320: {
321: int64_t v;
322:
323: v = llrint(a + (float64)INT64_MIN);
324:
325: return v - INT64_MIN;
326: }
327: uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
328: {
329: int64_t v;
330:
331: v = (int64_t)(a + (float64)INT64_MIN);
332:
333: return v - INT64_MIN;
334: }
335:
336:
337:
338:
339: #if defined(__sun__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
340: static inline float64 trunc(float64 x)
341: {
342: return x < 0 ? -floor(-x) : floor(x);
343: }
344: #endif
345: float64 float64_trunc_to_int( float64 a STATUS_PARAM )
346: {
347: return trunc(a);
348: }
349:
350: float64 float64_round_to_int( float64 a STATUS_PARAM )
351: {
352: #if defined(__arm__)
353: switch(STATUS(float_rounding_mode)) {
354: default:
355: case float_round_nearest_even:
356: asm("rndd %0, %1" : "=f" (a) : "f"(a));
357: break;
358: case float_round_down:
359: asm("rnddm %0, %1" : "=f" (a) : "f"(a));
360: break;
361: case float_round_up:
362: asm("rnddp %0, %1" : "=f" (a) : "f"(a));
363: break;
364: case float_round_to_zero:
365: asm("rnddz %0, %1" : "=f" (a) : "f"(a));
366: break;
367: }
368: #else
369: return rint(a);
370: #endif
371: }
372:
373: float64 float64_rem( float64 a, float64 b STATUS_PARAM)
374: {
375: return remainder(a, b);
376: }
377:
378: float64 float64_sqrt( float64 a STATUS_PARAM)
379: {
380: return sqrt(a);
381: }
382: int float64_compare( float64 a, float64 b STATUS_PARAM )
383: {
384: if (a < b) {
385: return -1;
386: } else if (a == b) {
387: return 0;
388: } else if (a > b) {
389: return 1;
390: } else {
391: return 2;
392: }
393: }
394: int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
395: {
396: if (isless(a, b)) {
397: return -1;
398: } else if (a == b) {
399: return 0;
400: } else if (isgreater(a, b)) {
401: return 1;
402: } else {
403: return 2;
404: }
405: }
406: int float64_is_signaling_nan( float64 a1)
407: {
408: float64u u;
409: uint64_t a;
410: u.f = a1;
411: a = u.i;
412: return
413: ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
414: && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
415:
416: }
417:
418: int float64_is_nan( float64 a1 )
419: {
420: float64u u;
421: uint64_t a;
422: u.f = a1;
423: a = u.i;
424:
425: return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
426:
427: }
428:
429: #ifdef FLOATX80
430:
431:
432:
433:
434: int floatx80_to_int32( floatx80 a STATUS_PARAM)
435: {
436: return long_to_int32(lrintl(a));
437: }
438: int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
439: {
440: return (int)a;
441: }
442: int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
443: {
444: return llrintl(a);
445: }
446: int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
447: {
448: return (int64_t)a;
449: }
450: float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
451: {
452: return a;
453: }
454: float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
455: {
456: return a;
457: }
458:
459:
460:
461:
462: floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
463: {
464: return rintl(a);
465: }
466: floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
467: {
468: return remainderl(a, b);
469: }
470: floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
471: {
472: return sqrtl(a);
473: }
474: int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
475: {
476: if (a < b) {
477: return -1;
478: } else if (a == b) {
479: return 0;
480: } else if (a > b) {
481: return 1;
482: } else {
483: return 2;
484: }
485: }
486: int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
487: {
488: if (isless(a, b)) {
489: return -1;
490: } else if (a == b) {
491: return 0;
492: } else if (isgreater(a, b)) {
493: return 1;
494: } else {
495: return 2;
496: }
497: }
498: int floatx80_is_signaling_nan( floatx80 a1)
499: {
500: floatx80u u;
501: u.f = a1;
502: return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
503: }
504:
505: #endif