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