1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33: #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
34: #define SNAN_BIT_IS_ONE 1
35: #else
36: #define SNAN_BIT_IS_ONE 0
37: #endif
38:
39:
40:
41:
42:
43: int8 float_detect_tininess = float_tininess_after_rounding;
44:
45:
46:
47:
48:
49:
50:
51:
52: void float_raise( int8 flags STATUS_PARAM )
53: {
54: STATUS(float_exception_flags) |= flags;
55: }
56:
57:
58:
59:
60: typedef struct {
61: flag sign;
62: bits64 high, low;
63: } commonNaNT;
64:
65:
66:
67:
68: #if defined(TARGET_SPARC)
69: #define float32_default_nan make_float32(0x7FFFFFFF)
70: #elif defined(TARGET_POWERPC)
71: #define float32_default_nan make_float32(0x7FC00000)
72: #elif defined(TARGET_HPPA)
73: #define float32_default_nan make_float32(0x7FA00000)
74: #elif SNAN_BIT_IS_ONE
75: #define float32_default_nan make_float32(0x7FBFFFFF)
76: #else
77: #define float32_default_nan make_float32(0xFFC00000)
78: #endif
79:
80:
81:
82:
83:
84:
85: int float32_is_nan( float32 a_ )
86: {
87: uint32_t a = float32_val(a_);
88: #if SNAN_BIT_IS_ONE
89: return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
90: #else
91: return ( 0xFF800000 <= (bits32) ( a<<1 ) );
92: #endif
93: }
94:
95:
96:
97:
98:
99:
100: int float32_is_signaling_nan( float32 a_ )
101: {
102: uint32_t a = float32_val(a_);
103: #if SNAN_BIT_IS_ONE
104: return ( 0xFF800000 <= (bits32) ( a<<1 ) );
105: #else
106: return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
107: #endif
108: }
109:
110:
111:
112:
113:
114:
115:
116: static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
117: {
118: commonNaNT z;
119:
120: if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
121: z.sign = float32_val(a)>>31;
122: z.low = 0;
123: z.high = ( (bits64) float32_val(a) )<<41;
124: return z;
125: }
126:
127:
128:
129:
130:
131:
132: static float32 commonNaNToFloat32( commonNaNT a )
133: {
134: bits32 mantissa = a.high>>41;
135: if ( mantissa )
136: return make_float32(
137: ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
138: else
139: return float32_default_nan;
140: }
141:
142:
143:
144:
145:
146:
147:
148: static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
149: {
150: flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
151: bits32 av, bv, res;
152:
153: aIsNaN = float32_is_nan( a );
154: aIsSignalingNaN = float32_is_signaling_nan( a );
155: bIsNaN = float32_is_nan( b );
156: bIsSignalingNaN = float32_is_signaling_nan( b );
157: av = float32_val(a);
158: bv = float32_val(b);
159: #if SNAN_BIT_IS_ONE
160: av &= ~0x00400000;
161: bv &= ~0x00400000;
162: #else
163: av |= 0x00400000;
164: bv |= 0x00400000;
165: #endif
166: if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
167: if ( aIsSignalingNaN ) {
168: if ( bIsSignalingNaN ) goto returnLargerSignificand;
169: res = bIsNaN ? bv : av;
170: }
171: else if ( aIsNaN ) {
172: if ( bIsSignalingNaN | ! bIsNaN )
173: res = av;
174: else {
175: returnLargerSignificand:
176: if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
177: res = bv;
178: else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
179: res = av;
180: else
181: res = ( av < bv ) ? av : bv;
182: }
183: }
184: else {
185: res = bv;
186: }
187: return make_float32(res);
188: }
189:
190:
191:
192:
193: #if defined(TARGET_SPARC)
194: #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
195: #elif defined(TARGET_POWERPC)
196: #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
197: #elif defined(TARGET_HPPA)
198: #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
199: #elif SNAN_BIT_IS_ONE
200: #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
201: #else
202: #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
203: #endif
204:
205:
206:
207:
208:
209:
210: int float64_is_nan( float64 a_ )
211: {
212: bits64 a = float64_val(a_);
213: #if SNAN_BIT_IS_ONE
214: return
215: ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
216: && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
217: #else
218: return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
219: #endif
220: }
221:
222:
223:
224:
225:
226:
227: int float64_is_signaling_nan( float64 a_ )
228: {
229: bits64 a = float64_val(a_);
230: #if SNAN_BIT_IS_ONE
231: return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
232: #else
233: return
234: ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
235: && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
236: #endif
237: }
238:
239:
240:
241:
242:
243:
244:
245: static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
246: {
247: commonNaNT z;
248:
249: if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
250: z.sign = float64_val(a)>>63;
251: z.low = 0;
252: z.high = float64_val(a)<<12;
253: return z;
254: }
255:
256:
257:
258:
259:
260:
261: static float64 commonNaNToFloat64( commonNaNT a )
262: {
263: bits64 mantissa = a.high>>12;
264:
265: if ( mantissa )
266: return make_float64(
267: ( ( (bits64) a.sign )<<63 )
268: | LIT64( 0x7FF0000000000000 )
269: | ( a.high>>12 ));
270: else
271: return float64_default_nan;
272: }
273:
274:
275:
276:
277:
278:
279:
280: static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
281: {
282: flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
283: bits64 av, bv, res;
284:
285: aIsNaN = float64_is_nan( a );
286: aIsSignalingNaN = float64_is_signaling_nan( a );
287: bIsNaN = float64_is_nan( b );
288: bIsSignalingNaN = float64_is_signaling_nan( b );
289: av = float64_val(a);
290: bv = float64_val(b);
291: #if SNAN_BIT_IS_ONE
292: av &= ~LIT64( 0x0008000000000000 );
293: bv &= ~LIT64( 0x0008000000000000 );
294: #else
295: av |= LIT64( 0x0008000000000000 );
296: bv |= LIT64( 0x0008000000000000 );
297: #endif
298: if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
299: if ( aIsSignalingNaN ) {
300: if ( bIsSignalingNaN ) goto returnLargerSignificand;
301: res = bIsNaN ? bv : av;
302: }
303: else if ( aIsNaN ) {
304: if ( bIsSignalingNaN | ! bIsNaN )
305: res = av;
306: else {
307: returnLargerSignificand:
308: if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
309: res = bv;
310: else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
311: res = av;
312: else
313: res = ( av < bv ) ? av : bv;
314: }
315: }
316: else {
317: res = bv;
318: }
319: return make_float64(res);
320: }
321:
322: #ifdef FLOATX80
323:
324:
325:
326:
327:
328:
329: #if SNAN_BIT_IS_ONE
330: #define floatx80_default_nan_high 0x7FFF
331: #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
332: #else
333: #define floatx80_default_nan_high 0xFFFF
334: #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
335: #endif
336:
337:
338:
339:
340:
341:
342: int floatx80_is_nan( floatx80 a )
343: {
344: #if SNAN_BIT_IS_ONE
345: bits64 aLow;
346:
347: aLow = a.low & ~ LIT64( 0x4000000000000000 );
348: return
349: ( ( a.high & 0x7FFF ) == 0x7FFF )
350: && (bits64) ( aLow<<1 )
351: && ( a.low == aLow );
352: #else
353: return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
354: #endif
355: }
356:
357:
358:
359:
360:
361:
362: int floatx80_is_signaling_nan( floatx80 a )
363: {
364: #if SNAN_BIT_IS_ONE
365: return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
366: #else
367: bits64 aLow;
368:
369: aLow = a.low & ~ LIT64( 0x4000000000000000 );
370: return
371: ( ( a.high & 0x7FFF ) == 0x7FFF )
372: && (bits64) ( aLow<<1 )
373: && ( a.low == aLow );
374: #endif
375: }
376:
377:
378:
379:
380:
381:
382:
383: static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
384: {
385: commonNaNT z;
386:
387: if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
388: z.sign = a.high>>15;
389: z.low = 0;
390: z.high = a.low;
391: return z;
392: }
393:
394:
395:
396:
397:
398:
399: static floatx80 commonNaNToFloatx80( commonNaNT a )
400: {
401: floatx80 z;
402:
403: if (a.high)
404: z.low = a.high;
405: else
406: z.low = floatx80_default_nan_low;
407: z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
408: return z;
409: }
410:
411:
412:
413:
414:
415:
416:
417: static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
418: {
419: flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
420:
421: aIsNaN = floatx80_is_nan( a );
422: aIsSignalingNaN = floatx80_is_signaling_nan( a );
423: bIsNaN = floatx80_is_nan( b );
424: bIsSignalingNaN = floatx80_is_signaling_nan( b );
425: #if SNAN_BIT_IS_ONE
426: a.low &= ~LIT64( 0xC000000000000000 );
427: b.low &= ~LIT64( 0xC000000000000000 );
428: #else
429: a.low |= LIT64( 0xC000000000000000 );
430: b.low |= LIT64( 0xC000000000000000 );
431: #endif
432: if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
433: if ( aIsSignalingNaN ) {
434: if ( bIsSignalingNaN ) goto returnLargerSignificand;
435: return bIsNaN ? b : a;
436: }
437: else if ( aIsNaN ) {
438: if ( bIsSignalingNaN | ! bIsNaN ) return a;
439: returnLargerSignificand:
440: if ( a.low < b.low ) return b;
441: if ( b.low < a.low ) return a;
442: return ( a.high < b.high ) ? a : b;
443: }
444: else {
445: return b;
446: }
447: }
448:
449: #endif
450:
451: #ifdef FLOAT128
452:
453:
454:
455:
456:
457: #if SNAN_BIT_IS_ONE
458: #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
459: #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
460: #else
461: #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
462: #define float128_default_nan_low LIT64( 0x0000000000000000 )
463: #endif
464:
465:
466:
467:
468:
469:
470: int float128_is_nan( float128 a )
471: {
472: #if SNAN_BIT_IS_ONE
473: return
474: ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
475: && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
476: #else
477: return
478: ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
479: && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
480: #endif
481: }
482:
483:
484:
485:
486:
487:
488: int float128_is_signaling_nan( float128 a )
489: {
490: #if SNAN_BIT_IS_ONE
491: return
492: ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
493: && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
494: #else
495: return
496: ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
497: && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
498: #endif
499: }
500:
501:
502:
503:
504:
505:
506:
507: static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
508: {
509: commonNaNT z;
510:
511: if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
512: z.sign = a.high>>63;
513: shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
514: return z;
515: }
516:
517:
518:
519:
520:
521:
522: static float128 commonNaNToFloat128( commonNaNT a )
523: {
524: float128 z;
525:
526: shift128Right( a.high, a.low, 16, &z.high, &z.low );
527: z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
528: return z;
529: }