|
|
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.8 root 5: #if defined(CONFIG_SOLARIS)
1.1.1.7 root 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.8 root 12: #if (defined(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__)) || \
13: (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
1.1 root 14: fpsetround(val);
15: #else
16: fesetround(val);
17: #endif
18: }
19:
20: #ifdef FLOATX80
21: void set_floatx80_rounding_precision(int val STATUS_PARAM)
22: {
23: STATUS(floatx80_rounding_precision) = val;
24: }
25: #endif
26:
1.1.1.8 root 27: #if defined(CONFIG_BSD) || \
28: (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
1.1.1.3 root 29: #define lrint(d) ((int32_t)rint(d))
30: #define llrint(d) ((int64_t)rint(d))
31: #define lrintf(f) ((int32_t)rint(f))
32: #define llrintf(f) ((int64_t)rint(f))
33: #define sqrtf(f) ((float)sqrt(f))
34: #define remainderf(fa, fb) ((float)remainder(fa, fb))
35: #define rintf(f) ((float)rint(f))
1.1.1.8 root 36: #if !defined(__sparc__) && \
37: (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
1.1.1.5 root 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.10! root 257: int float32_is_quiet_nan( float32 a1 )
1.1.1.6 root 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.8 root 352: #if defined(__sun__) && \
353: (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
1.1.1.5 root 354: static inline float64 trunc(float64 x)
355: {
356: return x < 0 ? -floor(-x) : floor(x);
357: }
358: #endif
1.1.1.4 root 359: float64 float64_trunc_to_int( float64 a STATUS_PARAM )
360: {
361: return trunc(a);
362: }
363:
1.1 root 364: float64 float64_round_to_int( float64 a STATUS_PARAM )
365: {
366: return rint(a);
367: }
368:
369: float64 float64_rem( float64 a, float64 b STATUS_PARAM)
370: {
371: return remainder(a, b);
372: }
373:
374: float64 float64_sqrt( float64 a STATUS_PARAM)
375: {
376: return sqrt(a);
377: }
1.1.1.4 root 378: int float64_compare( float64 a, float64 b STATUS_PARAM )
1.1 root 379: {
380: if (a < b) {
1.1.1.6 root 381: return float_relation_less;
1.1 root 382: } else if (a == b) {
1.1.1.6 root 383: return float_relation_equal;
1.1 root 384: } else if (a > b) {
1.1.1.6 root 385: return float_relation_greater;
1.1 root 386: } else {
1.1.1.6 root 387: return float_relation_unordered;
1.1 root 388: }
389: }
1.1.1.4 root 390: int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
1.1 root 391: {
392: if (isless(a, b)) {
1.1.1.6 root 393: return float_relation_less;
1.1 root 394: } else if (a == b) {
1.1.1.6 root 395: return float_relation_equal;
1.1 root 396: } else if (isgreater(a, b)) {
1.1.1.6 root 397: return float_relation_greater;
1.1 root 398: } else {
1.1.1.6 root 399: return float_relation_unordered;
1.1 root 400: }
401: }
1.1.1.4 root 402: int float64_is_signaling_nan( float64 a1)
1.1 root 403: {
404: float64u u;
405: uint64_t a;
406: u.f = a1;
407: a = u.i;
408: return
409: ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
410: && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
411:
412: }
413:
1.1.1.10! root 414: int float64_is_quiet_nan( float64 a1 )
1.1.1.4 root 415: {
416: float64u u;
417: uint64_t a;
418: u.f = a1;
419: a = u.i;
420:
1.1.1.6 root 421: return ( LIT64( 0xFFF0000000000000 ) < (bits64) ( a<<1 ) );
1.1.1.4 root 422:
423: }
424:
1.1 root 425: #ifdef FLOATX80
426:
427: /*----------------------------------------------------------------------------
428: | Software IEC/IEEE extended double-precision conversion routines.
429: *----------------------------------------------------------------------------*/
430: int floatx80_to_int32( floatx80 a STATUS_PARAM)
431: {
1.1.1.2 root 432: return long_to_int32(lrintl(a));
1.1 root 433: }
434: int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
435: {
436: return (int)a;
437: }
438: int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
439: {
440: return llrintl(a);
441: }
442: int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
443: {
444: return (int64_t)a;
445: }
446: float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
447: {
448: return a;
449: }
450: float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
451: {
452: return a;
453: }
454:
455: /*----------------------------------------------------------------------------
456: | Software IEC/IEEE extended double-precision operations.
457: *----------------------------------------------------------------------------*/
458: floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
459: {
460: return rintl(a);
461: }
462: floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
463: {
464: return remainderl(a, b);
465: }
466: floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
467: {
468: return sqrtl(a);
469: }
1.1.1.4 root 470: int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
1.1 root 471: {
472: if (a < b) {
1.1.1.6 root 473: return float_relation_less;
1.1 root 474: } else if (a == b) {
1.1.1.6 root 475: return float_relation_equal;
1.1 root 476: } else if (a > b) {
1.1.1.6 root 477: return float_relation_greater;
1.1 root 478: } else {
1.1.1.6 root 479: return float_relation_unordered;
1.1 root 480: }
481: }
1.1.1.4 root 482: int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
1.1 root 483: {
484: if (isless(a, b)) {
1.1.1.6 root 485: return float_relation_less;
1.1 root 486: } else if (a == b) {
1.1.1.6 root 487: return float_relation_equal;
1.1 root 488: } else if (isgreater(a, b)) {
1.1.1.6 root 489: return float_relation_greater;
1.1 root 490: } else {
1.1.1.6 root 491: return float_relation_unordered;
1.1 root 492: }
493: }
1.1.1.4 root 494: int floatx80_is_signaling_nan( floatx80 a1)
1.1 root 495: {
496: floatx80u u;
1.1.1.6 root 497: uint64_t aLow;
498: u.f = a1;
499:
500: aLow = u.i.low & ~ LIT64( 0x4000000000000000 );
501: return
502: ( ( u.i.high & 0x7FFF ) == 0x7FFF )
503: && (bits64) ( aLow<<1 )
504: && ( u.i.low == aLow );
505: }
506:
1.1.1.10! root 507: int floatx80_is_quiet_nan( floatx80 a1 )
1.1.1.6 root 508: {
509: floatx80u u;
1.1 root 510: u.f = a1;
511: return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
512: }
513:
514: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.