1 
2 /*
3 ===============================================================================
4 
5 This C source file is part of TestFloat, Release 2a, a package of programs
6 for testing the correctness of floating-point arithmetic complying to the
7 IEC/IEEE Standard for Floating-Point.
8 
9 Written by John R. Hauser.  More information is available through the Web
10 page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
11 
12 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
13 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
14 TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
15 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
16 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
17 
18 Derivative works are acceptable, even for commercial purposes, so long as
19 (1) they include prominent notice that the work is derivative, and (2) they
20 include prominent notice akin to these four paragraphs for those parts of
21 this code that are retained.
22 
23 ===============================================================================
24 */
25 
26 int8 slow_float_rounding_mode;
27 int8 slow_float_exception_flags;
28 int8 slow_float_detect_tininess;
29 #ifdef FLOATX80
30 int8 slow_floatx80_rounding_precision;
31 #endif
32 
33 typedef struct {
34     bits64 a0, a1;
35 } bits128X;
36 
37 typedef struct {
38     flag isNaN;
39     flag isInf;
40     flag isZero;
41     flag sign;
42     int32 exp;
43     bits128X sig;
44 } floatX;
45 
46 static const floatX floatXNaN = { TRUE, FALSE, FALSE, FALSE, 0, { 0, 0 } };
47 static const floatX floatXPositiveZero =
48     { FALSE, FALSE, TRUE, FALSE, 0, { 0, 0 } };
49 static const floatX floatXNegativeZero =
50     { FALSE, FALSE, TRUE, TRUE, 0, { 0, 0 } };
51 
shortShift128Left(bits128X a,int8 shiftCount)52 static bits128X shortShift128Left( bits128X a, int8 shiftCount )
53 {
54     int8 negShiftCount;
55 
56     negShiftCount = ( - shiftCount & 63 );
57     a.a0 = ( a.a0<<shiftCount ) | ( a.a1>>negShiftCount );
58     a.a1 <<= shiftCount;
59     return a;
60 
61 }
62 
shortShift128RightJamming(bits128X a,int8 shiftCount)63 static bits128X shortShift128RightJamming( bits128X a, int8 shiftCount )
64 {
65     int8 negShiftCount;
66     bits64 extra;
67 
68     negShiftCount = ( - shiftCount & 63 );
69     extra = a.a1<<negShiftCount;
70     a.a1 = ( a.a0<<negShiftCount ) | ( a.a1>>shiftCount ) | ( extra != 0 );
71     a.a0 >>= shiftCount;
72     return a;
73 
74 }
75 
neg128(bits128X a)76 static bits128X neg128( bits128X a )
77 {
78 
79     if ( a.a1 == 0 ) {
80         a.a0 = - a.a0;
81     }
82     else {
83         a.a1 = - a.a1;
84         a.a0 = ~ a.a0;
85     }
86     return a;
87 
88 }
89 
add128(bits128X a,bits128X b)90 static bits128X add128( bits128X a, bits128X b )
91 {
92 
93     a.a1 += b.a1;
94     a.a0 += b.a0 + ( a.a1 < b.a1 );
95     return a;
96 
97 }
98 
eq128(bits128X a,bits128X b)99 static flag eq128( bits128X a, bits128X b )
100 {
101 
102     return ( a.a0 == b.a0 ) && ( a.a1 == b.a1 );
103 
104 }
105 
le128(bits128X a,bits128X b)106 static flag le128( bits128X a, bits128X b )
107 {
108 
109     return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 <= b.a1 ) );
110 
111 }
112 
lt128(bits128X a,bits128X b)113 static flag lt128( bits128X a, bits128X b )
114 {
115 
116     return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 < b.a1 ) );
117 
118 }
119 
roundFloatXTo24(flag isTiny,floatX zx)120 static floatX roundFloatXTo24( flag isTiny, floatX zx )
121 {
122     bits32 roundBits;
123 
124     zx.sig.a0 |= ( zx.sig.a1 != 0 );
125     zx.sig.a1 = 0;
126     roundBits = zx.sig.a0 & 0xFFFFFFFF;
127     zx.sig.a0 -= roundBits;
128     if ( roundBits ) {
129         slow_float_exception_flags |= float_flag_inexact;
130         if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
131         switch ( slow_float_rounding_mode ) {
132          case float_round_nearest_even:
133             if ( roundBits < 0x80000000 ) goto noIncrement;
134             if (    ( roundBits == 0x80000000 )
135                  && ! ( zx.sig.a0 & LIT64( 0x100000000 ) ) ) {
136                 goto noIncrement;
137             }
138             break;
139          case float_round_to_zero:
140             goto noIncrement;
141          case float_round_down:
142             if ( ! zx.sign ) goto noIncrement;
143             break;
144          case float_round_up:
145             if ( zx.sign ) goto noIncrement;
146             break;
147         }
148         zx.sig.a0 += LIT64( 0x100000000 );
149         if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
150             zx.sig.a0 = LIT64( 0x0080000000000000 );
151             ++zx.exp;
152         }
153     }
154  noIncrement:
155     return zx;
156 
157 }
158 
roundFloatXTo53(flag isTiny,floatX zx)159 static floatX roundFloatXTo53( flag isTiny, floatX zx )
160 {
161     int8 roundBits;
162 
163     zx.sig.a0 |= ( zx.sig.a1 != 0 );
164     zx.sig.a1 = 0;
165     roundBits = zx.sig.a0 & 7;
166     zx.sig.a0 -= roundBits;
167     if ( roundBits ) {
168         slow_float_exception_flags |= float_flag_inexact;
169         if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
170         switch ( slow_float_rounding_mode ) {
171          case float_round_nearest_even:
172             if ( roundBits < 4 ) goto noIncrement;
173             if ( ( roundBits == 4 ) && ! ( zx.sig.a0 & 8 ) ) goto noIncrement;
174             break;
175          case float_round_to_zero:
176             goto noIncrement;
177          case float_round_down:
178             if ( ! zx.sign ) goto noIncrement;
179             break;
180          case float_round_up:
181             if ( zx.sign ) goto noIncrement;
182             break;
183         }
184         zx.sig.a0 += 8;
185         if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
186             zx.sig.a0 = LIT64( 0x0080000000000000 );
187             ++zx.exp;
188         }
189     }
190  noIncrement:
191     return zx;
192 
193 }
194 
roundFloatXTo64(flag isTiny,floatX zx)195 static floatX roundFloatXTo64( flag isTiny, floatX zx )
196 {
197     int64 roundBits;
198 
199     roundBits = zx.sig.a1 & LIT64( 0x00FFFFFFFFFFFFFF );
200     zx.sig.a1 -= roundBits;
201     if ( roundBits ) {
202         slow_float_exception_flags |= float_flag_inexact;
203         if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
204         switch ( slow_float_rounding_mode ) {
205          case float_round_nearest_even:
206             if ( roundBits < LIT64( 0x0080000000000000 ) ) goto noIncrement;
207             if (    ( roundBits == LIT64( 0x0080000000000000 ) )
208                  && ! ( zx.sig.a1 & LIT64( 0x0100000000000000 ) ) ) {
209                 goto noIncrement;
210             }
211             break;
212          case float_round_to_zero:
213             goto noIncrement;
214          case float_round_down:
215             if ( ! zx.sign ) goto noIncrement;
216             break;
217          case float_round_up:
218             if ( zx.sign ) goto noIncrement;
219             break;
220         }
221         zx.sig.a1 += LIT64( 0x0100000000000000 );
222         zx.sig.a0 += ( zx.sig.a1 == 0 );
223         if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
224             zx.sig.a0 = LIT64( 0x0080000000000000 );
225             ++zx.exp;
226         }
227     }
228  noIncrement:
229     return zx;
230 
231 }
232 
roundFloatXTo113(flag isTiny,floatX zx)233 static floatX roundFloatXTo113( flag isTiny, floatX zx )
234 {
235     int8 roundBits;
236 
237     roundBits = zx.sig.a1 & 0x7F;
238     zx.sig.a1 -= roundBits;
239     if ( roundBits ) {
240         slow_float_exception_flags |= float_flag_inexact;
241         if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
242         switch ( slow_float_rounding_mode ) {
243          case float_round_nearest_even:
244             if ( roundBits < 0x40 ) goto noIncrement;
245             if (    ( roundBits == 0x40 )
246                  && ! ( zx.sig.a1 & 0x80 ) ) goto noIncrement;
247             break;
248          case float_round_to_zero:
249             goto noIncrement;
250          case float_round_down:
251             if ( ! zx.sign ) goto noIncrement;
252             break;
253          case float_round_up:
254             if ( zx.sign ) goto noIncrement;
255             break;
256         }
257         zx.sig.a1 += 0x80;
258         zx.sig.a0 += ( zx.sig.a1 == 0 );
259         if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
260             zx.sig.a0 = LIT64( 0x0080000000000000 );
261             ++zx.exp;
262         }
263     }
264  noIncrement:
265     return zx;
266 
267 }
268 
int32ToFloatX(int32 a)269 static floatX int32ToFloatX( int32 a )
270 {
271     floatX ax;
272 
273     ax.isNaN = FALSE;
274     ax.isInf = FALSE;
275     ax.sign = ( a < 0 );
276     ax.sig.a1 = 0;
277     ax.sig.a0 = ax.sign ? - (bits64) a : a;
278     if ( a == 0 ) {
279         ax.isZero = TRUE;
280         return ax;
281     }
282     ax.isZero = FALSE;
283     ax.sig.a0 <<= 24;
284     ax.exp = 31;
285     while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
286         ax.sig.a0 <<= 1;
287         --ax.exp;
288     }
289     return ax;
290 
291 }
292 
floatXToInt32(floatX ax)293 static int32 floatXToInt32( floatX ax )
294 {
295     int8 savedExceptionFlags;
296     int32 shiftCount;
297     int32 z;
298 
299     if ( ax.isInf || ax.isNaN ) {
300         slow_float_exception_flags |= float_flag_invalid;
301         return ( ax.isInf & ax.sign ) ? (sbits32) 0x80000000 : 0x7FFFFFFF;
302     }
303     if ( ax.isZero ) return 0;
304     savedExceptionFlags = slow_float_exception_flags;
305     shiftCount = 52 - ax.exp;
306     if ( 56 < shiftCount ) {
307         ax.sig.a1 = 1;
308         ax.sig.a0 = 0;
309     }
310     else {
311         while ( 0 < shiftCount ) {
312             ax.sig = shortShift128RightJamming( ax.sig, 1 );
313             --shiftCount;
314         }
315     }
316     ax = roundFloatXTo53( FALSE, ax );
317     ax.sig = shortShift128RightJamming( ax.sig, 3 );
318     z = ax.sig.a0;
319     if ( ax.sign ) z = - z;
320     if (    ( shiftCount < 0 )
321          || ( ax.sig.a0>>32 )
322          || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
323        ) {
324         slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
325         return ax.sign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
326     }
327     return z;
328 
329 }
330 
int64ToFloatX(int64 a)331 static floatX int64ToFloatX( int64 a )
332 {
333     uint64 absA;
334     floatX ax;
335 
336     ax.isNaN = FALSE;
337     ax.isInf = FALSE;
338     ax.sign = ( a < 0 );
339     ax.sig.a1 = ax.sign ? - a : a;
340     ax.sig.a0 = 0;
341     if ( a == 0 ) {
342         ax.isZero = TRUE;
343         return ax;
344     }
345     ax.isZero = FALSE;
346     ax.sig = shortShift128Left( ax.sig, 56 );
347     ax.exp = 63;
348     while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
349         ax.sig = shortShift128Left( ax.sig, 1 );
350         --ax.exp;
351     }
352     return ax;
353 
354 }
355 
floatXToInt64(floatX ax)356 static int64 floatXToInt64( floatX ax )
357 {
358     int8 savedExceptionFlags;
359     int32 shiftCount;
360     int64 z;
361 
362     if ( ax.isInf || ax.isNaN ) {
363         slow_float_exception_flags |= float_flag_invalid;
364         return
365               ( ax.isInf & ax.sign ) ? (sbits64) LIT64( 0x8000000000000000 )
366             : LIT64( 0x7FFFFFFFFFFFFFFF );
367     }
368     if ( ax.isZero ) return 0;
369     savedExceptionFlags = slow_float_exception_flags;
370     shiftCount = 112 - ax.exp;
371     if ( 116 < shiftCount ) {
372         ax.sig.a1 = 1;
373         ax.sig.a0 = 0;
374     }
375     else {
376         while ( 0 < shiftCount ) {
377             ax.sig = shortShift128RightJamming( ax.sig, 1 );
378             --shiftCount;
379         }
380     }
381     ax = roundFloatXTo113( FALSE, ax );
382     ax.sig = shortShift128RightJamming( ax.sig, 7 );
383     z = ax.sig.a1;
384     if ( ax.sign ) z = - z;
385     if (    ( shiftCount < 0 )
386          || ax.sig.a0
387          || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
388        ) {
389         slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
390         return
391               ax.sign ? (sbits64) LIT64( 0x8000000000000000 )
392             : LIT64( 0x7FFFFFFFFFFFFFFF );
393     }
394     return z;
395 
396 }
397 
float32ToFloatX(float32 a)398 static floatX float32ToFloatX( float32 a )
399 {
400     int16 expField;
401     floatX ax;
402 
403     ax.isNaN = FALSE;
404     ax.isInf = FALSE;
405     ax.isZero = FALSE;
406     ax.sign = ( ( a & 0x80000000 ) != 0 );
407     expField = ( a>>23 ) & 0xFF;
408     ax.sig.a1 = 0;
409     ax.sig.a0 = a & 0x007FFFFF;
410     ax.sig.a0 <<= 32;
411     if ( expField == 0 ) {
412         if ( ax.sig.a0 == 0 ) {
413             ax.isZero = TRUE;
414         }
415         else {
416             expField = 1 - 0x7F;
417             do {
418                 ax.sig.a0 <<= 1;
419                 --expField;
420             } while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) );
421             ax.exp = expField;
422         }
423     }
424     else if ( expField == 0xFF ) {
425         if ( ax.sig.a0 == 0 ) {
426             ax.isInf = TRUE;
427         }
428         else {
429             ax.isNaN = TRUE;
430         }
431     }
432     else {
433         ax.sig.a0 |= LIT64( 0x0080000000000000 );
434         ax.exp = expField - 0x7F;
435     }
436     return ax;
437 
438 }
439 
floatXToFloat32(floatX zx)440 static float32 floatXToFloat32( floatX zx )
441 {
442     floatX savedZ;
443     flag isTiny;
444     int32 expField;
445     float32 z;
446 
447     if ( zx.isZero ) return zx.sign ? 0x80000000 : 0;
448     if ( zx.isInf ) return zx.sign ? 0xFF800000 : 0x7F800000;
449     if ( zx.isNaN ) return 0xFFFFFFFF;
450     while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
451         zx.sig = shortShift128RightJamming( zx.sig, 1 );
452         ++zx.exp;
453     }
454     while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
455         zx.sig = shortShift128Left( zx.sig, 1 );
456         --zx.exp;
457     }
458     savedZ = zx;
459     isTiny =
460            ( slow_float_detect_tininess == float_tininess_before_rounding )
461         && ( zx.exp + 0x7F <= 0 );
462     zx = roundFloatXTo24( isTiny, zx );
463     expField = zx.exp + 0x7F;
464     if ( 0xFF <= expField ) {
465         slow_float_exception_flags |=
466             float_flag_overflow | float_flag_inexact;
467         if ( zx.sign ) {
468             switch ( slow_float_rounding_mode ) {
469              case float_round_nearest_even:
470              case float_round_down:
471                 z = 0xFF800000;
472                 break;
473              case float_round_to_zero:
474              case float_round_up:
475                 z = 0xFF7FFFFF;
476                 break;
477             }
478         }
479         else {
480             switch ( slow_float_rounding_mode ) {
481              case float_round_nearest_even:
482              case float_round_up:
483                 z = 0x7F800000;
484                 break;
485              case float_round_to_zero:
486              case float_round_down:
487                 z = 0x7F7FFFFF;
488                 break;
489             }
490         }
491         return z;
492     }
493     if ( expField <= 0 ) {
494         isTiny = TRUE;
495         zx = savedZ;
496         expField = zx.exp + 0x7F;
497         if ( expField < -27 ) {
498             zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
499             zx.sig.a0 = 0;
500         }
501         else {
502             while ( expField <= 0 ) {
503                 zx.sig = shortShift128RightJamming( zx.sig, 1 );
504                 ++expField;
505             }
506         }
507         zx = roundFloatXTo24( isTiny, zx );
508         expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
509     }
510     z = expField;
511     z <<= 23;
512     if ( zx.sign ) z |= 0x80000000;
513     z |= ( zx.sig.a0>>32 ) & 0x007FFFFF;
514     return z;
515 
516 }
517 
float64ToFloatX(float64 a)518 static floatX float64ToFloatX( float64 a )
519 {
520     int16 expField;
521     floatX ax;
522 
523     ax.isNaN = FALSE;
524     ax.isInf = FALSE;
525     ax.isZero = FALSE;
526     ax.sign = ( ( a & LIT64( 0x8000000000000000 ) ) != 0 );
527     expField = ( a>>52 ) & 0x7FF;
528     ax.sig.a1 = 0;
529     ax.sig.a0 = a & LIT64( 0x000FFFFFFFFFFFFF );
530     if ( expField == 0 ) {
531         if ( ax.sig.a0 == 0 ) {
532             ax.isZero = TRUE;
533         }
534         else {
535             expField = 1 - 0x3FF;
536             do {
537                 ax.sig.a0 <<= 1;
538                 --expField;
539             } while ( ax.sig.a0 < LIT64( 0x0010000000000000 ) );
540             ax.exp = expField;
541         }
542     }
543     else if ( expField == 0x7FF ) {
544         if ( ax.sig.a0 == 0 ) {
545             ax.isInf = TRUE;
546         }
547         else {
548             ax.isNaN = TRUE;
549         }
550     }
551     else {
552         ax.exp = expField - 0x3FF;
553         ax.sig.a0 |= LIT64( 0x0010000000000000 );
554     }
555     ax.sig.a0 <<= 3;
556     return ax;
557 
558 }
559 
floatXToFloat64(floatX zx)560 static float64 floatXToFloat64( floatX zx )
561 {
562     floatX savedZ;
563     flag isTiny;
564     int32 expField;
565     float64 z;
566 
567     if ( zx.isZero ) return zx.sign ? LIT64( 0x8000000000000000 ) : 0;
568     if ( zx.isInf ) {
569         return
570               zx.sign ? LIT64( 0xFFF0000000000000 )
571             : LIT64( 0x7FF0000000000000 );
572     }
573     if ( zx.isNaN ) return LIT64( 0xFFFFFFFFFFFFFFFF );
574     while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
575         zx.sig = shortShift128RightJamming( zx.sig, 1 );
576         ++zx.exp;
577     }
578     while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
579         zx.sig = shortShift128Left( zx.sig, 1 );
580         --zx.exp;
581     }
582     savedZ = zx;
583     isTiny =
584            ( slow_float_detect_tininess == float_tininess_before_rounding )
585         && ( zx.exp + 0x3FF <= 0 );
586     zx = roundFloatXTo53( isTiny, zx );
587     expField = zx.exp + 0x3FF;
588     if ( 0x7FF <= expField ) {
589         slow_float_exception_flags |=
590             float_flag_overflow | float_flag_inexact;
591         if ( zx.sign ) {
592             switch ( slow_float_rounding_mode ) {
593              case float_round_nearest_even:
594              case float_round_down:
595                 z = LIT64( 0xFFF0000000000000 );
596                 break;
597              case float_round_to_zero:
598              case float_round_up:
599                 z = LIT64( 0xFFEFFFFFFFFFFFFF );
600                 break;
601             }
602         }
603         else {
604             switch ( slow_float_rounding_mode ) {
605              case float_round_nearest_even:
606              case float_round_up:
607                 z = LIT64( 0x7FF0000000000000 );
608                 break;
609              case float_round_to_zero:
610              case float_round_down:
611                 z = LIT64( 0x7FEFFFFFFFFFFFFF );
612                 break;
613             }
614         }
615         return z;
616     }
617     if ( expField <= 0 ) {
618         isTiny = TRUE;
619         zx = savedZ;
620         expField = zx.exp + 0x3FF;
621         if ( expField < -56 ) {
622             zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
623             zx.sig.a0 = 0;
624         }
625         else {
626             while ( expField <= 0 ) {
627                 zx.sig = shortShift128RightJamming( zx.sig, 1 );
628                 ++expField;
629             }
630         }
631         zx = roundFloatXTo53( isTiny, zx );
632         expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
633     }
634     zx.sig.a0 >>= 3;
635     z = expField;
636     z <<= 52;
637     if ( zx.sign ) z |= LIT64( 0x8000000000000000 );
638     z |= zx.sig.a0 & LIT64( 0x000FFFFFFFFFFFFF );
639     return z;
640 
641 }
642 
643 #ifdef FLOATX80
644 
floatx80ToFloatX(floatx80 a)645 static floatX floatx80ToFloatX( floatx80 a )
646 {
647     int32 expField;
648     floatX ax;
649 
650     ax.isNaN = FALSE;
651     ax.isInf = FALSE;
652     ax.isZero = FALSE;
653     ax.sign = ( ( a.high & 0x8000 ) != 0 );
654     expField = a.high & 0x7FFF;
655     ax.sig.a1 = a.low;
656     ax.sig.a0 = 0;
657     if ( expField == 0 ) {
658         if ( ax.sig.a1 == 0 ) {
659             ax.isZero = TRUE;
660         }
661         else {
662             expField = 1 - 0x3FFF;
663             while ( ax.sig.a1 < LIT64( 0x8000000000000000 ) ) {
664                 ax.sig.a1 <<= 1;
665                 --expField;
666             }
667             ax.exp = expField;
668         }
669     }
670     else if ( expField == 0x7FFF ) {
671         if ( ( ax.sig.a1 & LIT64( 0x7FFFFFFFFFFFFFFF ) ) == 0 ) {
672             ax.isInf = TRUE;
673         }
674         else {
675             ax.isNaN = TRUE;
676         }
677     }
678     else {
679         ax.exp = expField - 0x3FFF;
680     }
681     ax.sig = shortShift128Left( ax.sig, 56 );
682     return ax;
683 
684 }
685 
floatXToFloatx80(floatX zx)686 static floatx80 floatXToFloatx80( floatX zx )
687 {
688     floatX savedZ;
689     flag isTiny;
690     int32 expField;
691     floatx80 z;
692 
693     if ( zx.isZero ) {
694         z.low = 0;
695         z.high = zx.sign ? 0x8000 : 0;
696         return z;
697     }
698     if ( zx.isInf ) {
699         z.low = LIT64( 0x8000000000000000 );
700         z.high = zx.sign ? 0xFFFF : 0x7FFF;
701         return z;
702     }
703     if ( zx.isNaN ) {
704         z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
705         z.high = 0xFFFF;
706         return z;
707     }
708     while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
709         zx.sig = shortShift128RightJamming( zx.sig, 1 );
710         ++zx.exp;
711     }
712     while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
713         zx.sig = shortShift128Left( zx.sig, 1 );
714         --zx.exp;
715     }
716     savedZ = zx;
717     isTiny =
718            ( slow_float_detect_tininess == float_tininess_before_rounding )
719         && ( zx.exp + 0x3FFF <= 0 );
720     switch ( slow_floatx80_rounding_precision ) {
721      case 32:
722         zx = roundFloatXTo24( isTiny, zx );
723         break;
724      case 64:
725         zx = roundFloatXTo53( isTiny, zx );
726         break;
727      default:
728         zx = roundFloatXTo64( isTiny, zx );
729         break;
730     }
731     expField = zx.exp + 0x3FFF;
732     if ( 0x7FFF <= expField ) {
733         slow_float_exception_flags |=
734             float_flag_overflow | float_flag_inexact;
735         if ( zx.sign ) {
736             switch ( slow_float_rounding_mode ) {
737              case float_round_nearest_even:
738              case float_round_down:
739                 z.low = LIT64( 0x8000000000000000 );
740                 z.high = 0xFFFF;
741                 break;
742              case float_round_to_zero:
743              case float_round_up:
744                 switch ( slow_floatx80_rounding_precision ) {
745                  case 32:
746                     z.low = LIT64( 0xFFFFFF0000000000 );
747                     break;
748                  case 64:
749                     z.low = LIT64( 0xFFFFFFFFFFFFF800 );
750                     break;
751                  default:
752                     z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
753                     break;
754                 }
755                 z.high = 0xFFFE;
756                 break;
757             }
758         }
759         else {
760             switch ( slow_float_rounding_mode ) {
761              case float_round_nearest_even:
762              case float_round_up:
763                 z.low = LIT64( 0x8000000000000000 );
764                 z.high = 0x7FFF;
765                 break;
766              case float_round_to_zero:
767              case float_round_down:
768                 switch ( slow_floatx80_rounding_precision ) {
769                  case 32:
770                     z.low = LIT64( 0xFFFFFF0000000000 );
771                     break;
772                  case 64:
773                     z.low = LIT64( 0xFFFFFFFFFFFFF800 );
774                     break;
775                  default:
776                     z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
777                     break;
778                 }
779                 z.high = 0x7FFE;
780                 break;
781             }
782         }
783         return z;
784     }
785     if ( expField <= 0 ) {
786         isTiny = TRUE;
787         zx = savedZ;
788         expField = zx.exp + 0x3FFF;
789         if ( expField < -70 ) {
790             zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
791             zx.sig.a0 = 0;
792         }
793         else {
794             while ( expField <= 0 ) {
795                 zx.sig = shortShift128RightJamming( zx.sig, 1 );
796                 ++expField;
797             }
798         }
799         switch ( slow_floatx80_rounding_precision ) {
800          case 32:
801             zx = roundFloatXTo24( isTiny, zx );
802             break;
803          case 64:
804             zx = roundFloatXTo53( isTiny, zx );
805             break;
806          default:
807             zx = roundFloatXTo64( isTiny, zx );
808             break;
809         }
810         expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
811     }
812     zx.sig = shortShift128RightJamming( zx.sig, 56 );
813     z.low = zx.sig.a1;
814     z.high = expField;
815     if ( zx.sign ) z.high |= 0x8000;
816     return z;
817 
818 }
819 
820 #endif
821 
822 #ifdef FLOAT128
823 
float128ToFloatX(float128 a)824 static floatX float128ToFloatX( float128 a )
825 {
826     int32 expField;
827     floatX ax;
828 
829     ax.isNaN = FALSE;
830     ax.isInf = FALSE;
831     ax.isZero = FALSE;
832     ax.sign = ( ( a.high & LIT64( 0x8000000000000000 ) ) != 0 );
833     expField = ( a.high>>48 ) & 0x7FFF;
834     ax.sig.a1 = a.low;
835     ax.sig.a0 = a.high & LIT64( 0x0000FFFFFFFFFFFF );
836     if ( expField == 0 ) {
837         if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
838             ax.isZero = TRUE;
839         }
840         else {
841             expField = 1 - 0x3FFF;
842             do {
843                 ax.sig = shortShift128Left( ax.sig, 1 );
844                 --expField;
845             } while ( ax.sig.a0 < LIT64( 0x0001000000000000 ) );
846             ax.exp = expField;
847         }
848     }
849     else if ( expField == 0x7FFF ) {
850         if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
851             ax.isInf = TRUE;
852         }
853         else {
854             ax.isNaN = TRUE;
855         }
856     }
857     else {
858         ax.exp = expField - 0x3FFF;
859         ax.sig.a0 |= LIT64( 0x0001000000000000 );
860     }
861     ax.sig = shortShift128Left( ax.sig, 7 );
862     return ax;
863 
864 }
865 
floatXToFloat128(floatX zx)866 static float128 floatXToFloat128( floatX zx )
867 {
868     floatX savedZ;
869     flag isTiny;
870     int32 expField;
871     float128 z;
872 
873     if ( zx.isZero ) {
874         z.low = 0;
875         z.high = zx.sign ? LIT64( 0x8000000000000000 ) : 0;
876         return z;
877     }
878     if ( zx.isInf ) {
879         z.low = 0;
880         z.high =
881               zx.sign ? LIT64( 0xFFFF000000000000 )
882             : LIT64( 0x7FFF000000000000 );
883         return z;
884     }
885     if ( zx.isNaN ) {
886         z.high = z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
887         return z;
888     }
889     while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
890         zx.sig = shortShift128RightJamming( zx.sig, 1 );
891         ++zx.exp;
892     }
893     while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
894         zx.sig = shortShift128Left( zx.sig, 1 );
895         --zx.exp;
896     }
897     savedZ = zx;
898     isTiny =
899            ( slow_float_detect_tininess == float_tininess_before_rounding )
900         && ( zx.exp + 0x3FFF <= 0 );
901     zx = roundFloatXTo113( isTiny, zx );
902     expField = zx.exp + 0x3FFF;
903     if ( 0x7FFF <= expField ) {
904         slow_float_exception_flags |=
905             float_flag_overflow | float_flag_inexact;
906         if ( zx.sign ) {
907             switch ( slow_float_rounding_mode ) {
908              case float_round_nearest_even:
909              case float_round_down:
910                 z.low = 0;
911                 z.high = LIT64( 0xFFFF000000000000 );
912                 break;
913              case float_round_to_zero:
914              case float_round_up:
915                 z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
916                 z.high = LIT64( 0xFFFEFFFFFFFFFFFF );
917                 break;
918             }
919         }
920         else {
921             switch ( slow_float_rounding_mode ) {
922              case float_round_nearest_even:
923              case float_round_up:
924                 z.low = 0;
925                 z.high = LIT64( 0x7FFF000000000000 );
926                 break;
927              case float_round_to_zero:
928              case float_round_down:
929                 z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
930                 z.high = LIT64( 0x7FFEFFFFFFFFFFFF );
931                 break;
932             }
933         }
934         return z;
935     }
936     if ( expField <= 0 ) {
937         isTiny = TRUE;
938         zx = savedZ;
939         expField = zx.exp + 0x3FFF;
940         if ( expField < -120 ) {
941             zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
942             zx.sig.a0 = 0;
943         }
944         else {
945             while ( expField <= 0 ) {
946                 zx.sig = shortShift128RightJamming( zx.sig, 1 );
947                 ++expField;
948             }
949         }
950         zx = roundFloatXTo113( isTiny, zx );
951         expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
952     }
953     zx.sig = shortShift128RightJamming( zx.sig, 7 );
954     z.low = zx.sig.a1;
955     z.high = expField;
956     z.high <<= 48;
957     if ( zx.sign ) z.high |= LIT64( 0x8000000000000000 );
958     z.high |= zx.sig.a0 & LIT64( 0x0000FFFFFFFFFFFF );
959     return z;
960 
961 }
962 
963 #endif
964 
floatXInvalid(void)965 static floatX floatXInvalid( void )
966 {
967 
968     slow_float_exception_flags |= float_flag_invalid;
969     return floatXNaN;
970 
971 }
972 
floatXRoundToInt(floatX ax)973 static floatX floatXRoundToInt( floatX ax )
974 {
975     int32 shiftCount, i;
976 
977     if ( ax.isNaN || ax.isInf ) return ax;
978     shiftCount = 112 - ax.exp;
979     if ( shiftCount <= 0 ) return ax;
980     if ( 119 < shiftCount ) {
981         ax.exp = 112;
982         ax.sig.a1 = ! ax.isZero;
983         ax.sig.a0 = 0;
984     }
985     else {
986         while ( 0 < shiftCount ) {
987             ax.sig = shortShift128RightJamming( ax.sig, 1 );
988             ++ax.exp;
989             --shiftCount;
990         }
991     }
992     ax = roundFloatXTo113( FALSE, ax );
993     if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
994     return ax;
995 
996 }
997 
floatXAdd(floatX ax,floatX bx)998 static floatX floatXAdd( floatX ax, floatX bx )
999 {
1000     int32 expDiff;
1001     floatX zx;
1002 
1003     if ( ax.isNaN ) return ax;
1004     if ( bx.isNaN ) return bx;
1005     if ( ax.isInf && bx.isInf ) {
1006         if ( ax.sign == bx.sign ) return ax;
1007         return floatXInvalid();
1008     }
1009     if ( ax.isInf ) return ax;
1010     if ( bx.isInf ) return bx;
1011     if ( ax.isZero && bx.isZero ) {
1012         if ( ax.sign == bx.sign ) return ax;
1013         goto completeCancellation;
1014     }
1015     if (    ( ax.sign != bx.sign )
1016          && ( ax.exp == bx.exp )
1017          && eq128( ax.sig, bx.sig )
1018        ) {
1019  completeCancellation:
1020         return
1021               ( slow_float_rounding_mode == float_round_down ) ?
1022                   floatXNegativeZero
1023             : floatXPositiveZero;
1024     }
1025     if ( ax.isZero ) return bx;
1026     if ( bx.isZero ) return ax;
1027     expDiff = ax.exp - bx.exp;
1028     if ( expDiff < 0 ) {
1029         zx = ax;
1030         zx.exp = bx.exp;
1031         if ( expDiff < -120 ) {
1032             zx.sig.a1 = 1;
1033             zx.sig.a0 = 0;
1034         }
1035         else {
1036             while ( expDiff < 0 ) {
1037                 zx.sig = shortShift128RightJamming( zx.sig, 1 );
1038                 ++expDiff;
1039             }
1040         }
1041         if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
1042         zx.sign = bx.sign;
1043         zx.sig = add128( zx.sig, bx.sig );
1044     }
1045     else {
1046         zx = bx;
1047         zx.exp = ax.exp;
1048         if ( 120 < expDiff ) {
1049             zx.sig.a1 = 1;
1050             zx.sig.a0 = 0;
1051         }
1052         else {
1053             while ( 0 < expDiff ) {
1054                 zx.sig = shortShift128RightJamming( zx.sig, 1 );
1055                 --expDiff;
1056             }
1057         }
1058         if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
1059         zx.sign = ax.sign;
1060         zx.sig = add128( zx.sig, ax.sig );
1061     }
1062     if ( zx.sig.a0 & LIT64( 0x8000000000000000 ) ) {
1063         zx.sig = neg128( zx.sig );
1064         zx.sign = ! zx.sign;
1065     }
1066     return zx;
1067 
1068 }
1069 
floatXMul(floatX ax,floatX bx)1070 static floatX floatXMul( floatX ax, floatX bx )
1071 {
1072     int8 bitNum;
1073     floatX zx;
1074 
1075     if ( ax.isNaN ) return ax;
1076     if ( bx.isNaN ) return bx;
1077     if ( ax.isInf ) {
1078         if ( bx.isZero ) return floatXInvalid();
1079         if ( bx.sign ) ax.sign = ! ax.sign;
1080         return ax;
1081     }
1082     if ( bx.isInf ) {
1083         if ( ax.isZero ) return floatXInvalid();
1084         if ( ax.sign ) bx.sign = ! bx.sign;
1085         return bx;
1086     }
1087     zx = ax;
1088     zx.sign ^= bx.sign;
1089     if ( ax.isZero || bx.isZero ) {
1090         return zx.sign ? floatXNegativeZero : floatXPositiveZero;
1091     }
1092     zx.exp += bx.exp + 1;
1093     zx.sig.a1 = 0;
1094     zx.sig.a0 = 0;
1095     for ( bitNum = 0; bitNum < 119; ++bitNum ) {
1096         if ( bx.sig.a1 & 2 ) zx.sig = add128( zx.sig, ax.sig );
1097         bx.sig = shortShift128RightJamming( bx.sig, 1 );
1098         zx.sig = shortShift128RightJamming( zx.sig, 1 );
1099     }
1100     return zx;
1101 
1102 }
1103 
floatXDiv(floatX ax,floatX bx)1104 static floatX floatXDiv( floatX ax, floatX bx )
1105 {
1106     bits128X negBSig;
1107     int8 bitNum;
1108     floatX zx;
1109 
1110     if ( ax.isNaN ) return ax;
1111     if ( bx.isNaN ) return bx;
1112     if ( ax.isInf ) {
1113         if ( bx.isInf ) return floatXInvalid();
1114         if ( bx.sign ) ax.sign = ! ax.sign;
1115         return ax;
1116     }
1117     if ( bx.isZero ) {
1118         if ( ax.isZero ) return floatXInvalid();
1119         slow_float_exception_flags |= float_flag_divbyzero;
1120         if ( ax.sign ) bx.sign = ! bx.sign;
1121         bx.isZero = FALSE;
1122         bx.isInf = TRUE;
1123         return bx;
1124     }
1125     zx = ax;
1126     zx.sign ^= bx.sign;
1127     if ( ax.isZero || bx.isInf ) {
1128         return zx.sign ? floatXNegativeZero : floatXPositiveZero;
1129     }
1130     zx.exp -= bx.exp + 1;
1131     zx.sig.a1 = 0;
1132     zx.sig.a0 = 0;
1133     negBSig = neg128( bx.sig );
1134     for ( bitNum = 0; bitNum < 120; ++bitNum ) {
1135         if ( le128( bx.sig, ax.sig ) ) {
1136             zx.sig.a1 |= 1;
1137             ax.sig = add128( ax.sig, negBSig );
1138         }
1139         ax.sig = shortShift128Left( ax.sig, 1 );
1140         zx.sig = shortShift128Left( zx.sig, 1 );
1141     }
1142     if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
1143     return zx;
1144 
1145 }
1146 
floatXRem(floatX ax,floatX bx)1147 static floatX floatXRem( floatX ax, floatX bx )
1148 {
1149     bits128X negBSig;
1150     flag lastQuotientBit;
1151     bits128X savedASig;
1152 
1153     if ( ax.isNaN ) return ax;
1154     if ( bx.isNaN ) return bx;
1155     if ( ax.isInf || bx.isZero ) return floatXInvalid();
1156     if ( ax.isZero || bx.isInf ) return ax;
1157     --bx.exp;
1158     if ( ax.exp < bx.exp ) return ax;
1159     bx.sig = shortShift128Left( bx.sig, 1 );
1160     negBSig = neg128( bx.sig );
1161     while ( bx.exp < ax.exp ) {
1162         if ( le128( bx.sig, ax.sig ) ) ax.sig = add128( ax.sig, negBSig );
1163         ax.sig = shortShift128Left( ax.sig, 1 );
1164         --ax.exp;
1165     }
1166     lastQuotientBit = le128( bx.sig, ax.sig );
1167     if ( lastQuotientBit ) ax.sig = add128( ax.sig, negBSig );
1168     savedASig = ax.sig;
1169     ax.sig = neg128( add128( ax.sig, negBSig ) );
1170     if ( lt128( ax.sig, savedASig ) ) {
1171         ax.sign = ! ax.sign;
1172     }
1173     else if ( lt128( savedASig, ax.sig ) ) {
1174         ax.sig = savedASig;
1175     }
1176     else {
1177         if ( lastQuotientBit ) {
1178             ax.sign = ! ax.sign;
1179         }
1180         else {
1181             ax.sig = savedASig;
1182         }
1183     }
1184     if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
1185     return ax;
1186 
1187 }
1188 
floatXSqrt(floatX ax)1189 static floatX floatXSqrt( floatX ax )
1190 {
1191     int8 bitNum;
1192     bits128X bitSig, savedASig;
1193     floatX zx;
1194 
1195     if ( ax.isNaN || ax.isZero ) return ax;
1196     if ( ax.sign ) return floatXInvalid();
1197     if ( ax.isInf ) return ax;
1198     zx = ax;
1199     zx.exp >>= 1;
1200     if ( ( ax.exp & 1 ) == 0 ) ax.sig = shortShift128RightJamming( ax.sig, 1 );
1201     zx.sig.a1 = 0;
1202     zx.sig.a0 = 0;
1203     bitSig.a1 = 0;
1204     bitSig.a0 = LIT64( 0x0080000000000000 );
1205     for ( bitNum = 0; bitNum < 120; ++bitNum ) {
1206         savedASig = ax.sig;
1207         ax.sig = add128( ax.sig, neg128( zx.sig ) );
1208         ax.sig = shortShift128Left( ax.sig, 1 );
1209         ax.sig = add128( ax.sig, neg128( bitSig ) );
1210         if ( ax.sig.a0 & LIT64( 0x8000000000000000 ) ) {
1211             ax.sig = shortShift128Left( savedASig, 1 );
1212         }
1213         else {
1214             zx.sig.a1 |= bitSig.a1;
1215             zx.sig.a0 |= bitSig.a0;
1216         }
1217         bitSig = shortShift128RightJamming( bitSig, 1 );
1218     }
1219     if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
1220     return zx;
1221 
1222 }
1223 
floatXEq(floatX ax,floatX bx)1224 static flag floatXEq( floatX ax, floatX bx )
1225 {
1226 
1227     if ( ax.isNaN || bx.isNaN ) return FALSE;
1228     if ( ax.isZero && bx.isZero ) return TRUE;
1229     if ( ax.sign != bx.sign ) return FALSE;
1230     if ( ax.isInf || bx.isInf ) return ax.isInf && bx.isInf;
1231     return ( ax.exp == bx.exp ) && eq128( ax.sig, bx.sig );
1232 
1233 }
1234 
floatXLe(floatX ax,floatX bx)1235 static flag floatXLe( floatX ax, floatX bx )
1236 {
1237 
1238     if ( ax.isNaN || bx.isNaN ) return FALSE;
1239     if ( ax.isZero && bx.isZero ) return TRUE;
1240     if ( ax.sign != bx.sign ) return ax.sign;
1241     if ( ax.sign ) {
1242         if ( ax.isInf || bx.isZero ) return TRUE;
1243         if ( bx.isInf || ax.isZero ) return FALSE;
1244         if ( bx.exp < ax.exp ) return TRUE;
1245         if ( ax.exp < bx.exp ) return FALSE;
1246         return le128( bx.sig, ax.sig );
1247     }
1248     else {
1249         if ( bx.isInf || ax.isZero ) return TRUE;
1250         if ( ax.isInf || bx.isZero ) return FALSE;
1251         if ( ax.exp < bx.exp ) return TRUE;
1252         if ( bx.exp < ax.exp ) return FALSE;
1253         return le128( ax.sig, bx.sig );
1254     }
1255 
1256 }
1257 
floatXLt(floatX ax,floatX bx)1258 static flag floatXLt( floatX ax, floatX bx )
1259 {
1260 
1261     if ( ax.isNaN || bx.isNaN ) return FALSE;
1262     if ( ax.isZero && bx.isZero ) return FALSE;
1263     if ( ax.sign != bx.sign ) return ax.sign;
1264     if ( ax.isInf && bx.isInf ) return FALSE;
1265     if ( ax.sign ) {
1266         if ( ax.isInf || bx.isZero ) return TRUE;
1267         if ( bx.isInf || ax.isZero ) return FALSE;
1268         if ( bx.exp < ax.exp ) return TRUE;
1269         if ( ax.exp < bx.exp ) return FALSE;
1270         return lt128( bx.sig, ax.sig );
1271     }
1272     else {
1273         if ( bx.isInf || ax.isZero ) return TRUE;
1274         if ( ax.isInf || bx.isZero ) return FALSE;
1275         if ( ax.exp < bx.exp ) return TRUE;
1276         if ( bx.exp < ax.exp ) return FALSE;
1277         return lt128( ax.sig, bx.sig );
1278     }
1279 
1280 }
1281 
slow_int32_to_float32(int32 a)1282 float32 slow_int32_to_float32( int32 a )
1283 {
1284 
1285     return floatXToFloat32( int32ToFloatX( a ) );
1286 
1287 }
1288 
slow_int32_to_float64(int32 a)1289 float64 slow_int32_to_float64( int32 a )
1290 {
1291 
1292     return floatXToFloat64( int32ToFloatX( a ) );
1293 
1294 }
1295 
1296 #ifdef FLOATX80
1297 
slow_int32_to_floatx80(int32 a)1298 floatx80 slow_int32_to_floatx80( int32 a )
1299 {
1300 
1301     return floatXToFloatx80( int32ToFloatX( a ) );
1302 
1303 }
1304 
1305 #endif
1306 
1307 #ifdef FLOAT128
1308 
slow_int32_to_float128(int32 a)1309 float128 slow_int32_to_float128( int32 a )
1310 {
1311 
1312     return floatXToFloat128( int32ToFloatX( a ) );
1313 
1314 }
1315 
1316 #endif
1317 
slow_int64_to_float32(int64 a)1318 float32 slow_int64_to_float32( int64 a )
1319 {
1320 
1321     return floatXToFloat32( int64ToFloatX( a ) );
1322 
1323 }
1324 
slow_int64_to_float64(int64 a)1325 float64 slow_int64_to_float64( int64 a )
1326 {
1327 
1328     return floatXToFloat64( int64ToFloatX( a ) );
1329 
1330 }
1331 
1332 #ifdef FLOATX80
1333 
slow_int64_to_floatx80(int64 a)1334 floatx80 slow_int64_to_floatx80( int64 a )
1335 {
1336 
1337     return floatXToFloatx80( int64ToFloatX( a ) );
1338 
1339 }
1340 
1341 #endif
1342 
1343 #ifdef FLOAT128
1344 
slow_int64_to_float128(int64 a)1345 float128 slow_int64_to_float128( int64 a )
1346 {
1347 
1348     return floatXToFloat128( int64ToFloatX( a ) );
1349 
1350 }
1351 
1352 #endif
1353 
slow_float32_to_int32(float32 a)1354 int32 slow_float32_to_int32( float32 a )
1355 {
1356 
1357     return floatXToInt32( float32ToFloatX( a ) );
1358 
1359 }
1360 
slow_float32_to_int32_round_to_zero(float32 a)1361 int32 slow_float32_to_int32_round_to_zero( float32 a )
1362 {
1363     int8 savedRoundingMode;
1364     int32 z;
1365 
1366     savedRoundingMode = slow_float_rounding_mode;
1367     slow_float_rounding_mode = float_round_to_zero;
1368     z = floatXToInt32( float32ToFloatX( a ) );
1369     slow_float_rounding_mode = savedRoundingMode;
1370     return z;
1371 
1372 }
1373 
slow_float32_to_int64(float32 a)1374 int64 slow_float32_to_int64( float32 a )
1375 {
1376 
1377     return floatXToInt64( float32ToFloatX( a ) );
1378 
1379 }
1380 
slow_float32_to_int64_round_to_zero(float32 a)1381 int64 slow_float32_to_int64_round_to_zero( float32 a )
1382 {
1383     int8 savedRoundingMode;
1384     int64 z;
1385 
1386     savedRoundingMode = slow_float_rounding_mode;
1387     slow_float_rounding_mode = float_round_to_zero;
1388     z = floatXToInt64( float32ToFloatX( a ) );
1389     slow_float_rounding_mode = savedRoundingMode;
1390     return z;
1391 
1392 }
1393 
slow_float32_to_float64(float32 a)1394 float64 slow_float32_to_float64( float32 a )
1395 {
1396 
1397     return floatXToFloat64( float32ToFloatX( a ) );
1398 
1399 }
1400 
1401 #ifdef FLOATX80
1402 
slow_float32_to_floatx80(float32 a)1403 floatx80 slow_float32_to_floatx80( float32 a )
1404 {
1405 
1406     return floatXToFloatx80( float32ToFloatX( a ) );
1407 
1408 }
1409 
1410 #endif
1411 
1412 #ifdef FLOAT128
1413 
slow_float32_to_float128(float32 a)1414 float128 slow_float32_to_float128( float32 a )
1415 {
1416 
1417     return floatXToFloat128( float32ToFloatX( a ) );
1418 
1419 }
1420 
1421 #endif
1422 
slow_float32_round_to_int(float32 a)1423 float32 slow_float32_round_to_int( float32 a )
1424 {
1425 
1426     return floatXToFloat32( floatXRoundToInt( float32ToFloatX( a ) ) );
1427 
1428 }
1429 
slow_float32_add(float32 a,float32 b)1430 float32 slow_float32_add( float32 a, float32 b )
1431 {
1432 
1433     return
1434         floatXToFloat32(
1435             floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1436 
1437 }
1438 
slow_float32_sub(float32 a,float32 b)1439 float32 slow_float32_sub( float32 a, float32 b )
1440 {
1441 
1442     b ^= 0x80000000;
1443     return
1444         floatXToFloat32(
1445             floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1446 
1447 }
1448 
slow_float32_mul(float32 a,float32 b)1449 float32 slow_float32_mul( float32 a, float32 b )
1450 {
1451 
1452     return
1453         floatXToFloat32(
1454             floatXMul( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1455 
1456 }
1457 
slow_float32_div(float32 a,float32 b)1458 float32 slow_float32_div( float32 a, float32 b )
1459 {
1460 
1461     return
1462         floatXToFloat32(
1463             floatXDiv( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1464 
1465 }
1466 
slow_float32_rem(float32 a,float32 b)1467 float32 slow_float32_rem( float32 a, float32 b )
1468 {
1469 
1470     return
1471         floatXToFloat32(
1472             floatXRem( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1473 
1474 }
1475 
slow_float32_sqrt(float32 a)1476 float32 slow_float32_sqrt( float32 a )
1477 {
1478 
1479     return floatXToFloat32( floatXSqrt( float32ToFloatX( a ) ) );
1480 
1481 }
1482 
slow_float32_eq(float32 a,float32 b)1483 flag slow_float32_eq( float32 a, float32 b )
1484 {
1485 
1486     return floatXEq( float32ToFloatX( a ), float32ToFloatX( b ) );
1487 
1488 }
1489 
slow_float32_le(float32 a,float32 b)1490 flag slow_float32_le( float32 a, float32 b )
1491 {
1492     floatX ax, bx;
1493 
1494     ax = float32ToFloatX( a );
1495     bx = float32ToFloatX( b );
1496     if ( ax.isNaN || bx.isNaN ) {
1497         slow_float_exception_flags |= float_flag_invalid;
1498     }
1499     return floatXLe( ax, bx );
1500 
1501 }
1502 
slow_float32_lt(float32 a,float32 b)1503 flag slow_float32_lt( float32 a, float32 b )
1504 {
1505     floatX ax, bx;
1506 
1507     ax = float32ToFloatX( a );
1508     bx = float32ToFloatX( b );
1509     if ( ax.isNaN || bx.isNaN ) {
1510         slow_float_exception_flags |= float_flag_invalid;
1511     }
1512     return floatXLt( ax, bx );
1513 
1514 }
1515 
slow_float32_eq_signaling(float32 a,float32 b)1516 flag slow_float32_eq_signaling( float32 a, float32 b )
1517 {
1518     floatX ax, bx;
1519 
1520     ax = float32ToFloatX( a );
1521     bx = float32ToFloatX( b );
1522     if ( ax.isNaN || bx.isNaN ) {
1523         slow_float_exception_flags |= float_flag_invalid;
1524     }
1525     return floatXEq( ax, bx );
1526 
1527 }
1528 
slow_float32_le_quiet(float32 a,float32 b)1529 flag slow_float32_le_quiet( float32 a, float32 b )
1530 {
1531 
1532     return floatXLe( float32ToFloatX( a ), float32ToFloatX( b ) );
1533 
1534 }
1535 
slow_float32_lt_quiet(float32 a,float32 b)1536 flag slow_float32_lt_quiet( float32 a, float32 b )
1537 {
1538 
1539     return floatXLt( float32ToFloatX( a ), float32ToFloatX( b ) );
1540 
1541 }
1542 
slow_float64_to_int32(float64 a)1543 int32 slow_float64_to_int32( float64 a )
1544 {
1545 
1546     return floatXToInt32( float64ToFloatX( a ) );
1547 
1548 }
1549 
slow_float64_to_int32_round_to_zero(float64 a)1550 int32 slow_float64_to_int32_round_to_zero( float64 a )
1551 {
1552     int8 savedRoundingMode;
1553     int32 z;
1554 
1555     savedRoundingMode = slow_float_rounding_mode;
1556     slow_float_rounding_mode = float_round_to_zero;
1557     z = floatXToInt32( float64ToFloatX( a ) );
1558     slow_float_rounding_mode = savedRoundingMode;
1559     return z;
1560 
1561 }
1562 
slow_float64_to_int64(float64 a)1563 int64 slow_float64_to_int64( float64 a )
1564 {
1565 
1566     return floatXToInt64( float64ToFloatX( a ) );
1567 
1568 }
1569 
slow_float64_to_int64_round_to_zero(float64 a)1570 int64 slow_float64_to_int64_round_to_zero( float64 a )
1571 {
1572     int8 savedRoundingMode;
1573     int64 z;
1574 
1575     savedRoundingMode = slow_float_rounding_mode;
1576     slow_float_rounding_mode = float_round_to_zero;
1577     z = floatXToInt64( float64ToFloatX( a ) );
1578     slow_float_rounding_mode = savedRoundingMode;
1579     return z;
1580 
1581 }
1582 
slow_float64_to_float32(float64 a)1583 float32 slow_float64_to_float32( float64 a )
1584 {
1585 
1586     return floatXToFloat32( float64ToFloatX( a ) );
1587 
1588 }
1589 
1590 #ifdef FLOATX80
1591 
slow_float64_to_floatx80(float64 a)1592 floatx80 slow_float64_to_floatx80( float64 a )
1593 {
1594 
1595     return floatXToFloatx80( float64ToFloatX( a ) );
1596 
1597 }
1598 
1599 #endif
1600 
1601 #ifdef FLOAT128
1602 
slow_float64_to_float128(float64 a)1603 float128 slow_float64_to_float128( float64 a )
1604 {
1605 
1606     return floatXToFloat128( float64ToFloatX( a ) );
1607 
1608 }
1609 
1610 #endif
1611 
slow_float64_round_to_int(float64 a)1612 float64 slow_float64_round_to_int( float64 a )
1613 {
1614 
1615     return floatXToFloat64( floatXRoundToInt( float64ToFloatX( a ) ) );
1616 
1617 }
1618 
slow_float64_add(float64 a,float64 b)1619 float64 slow_float64_add( float64 a, float64 b )
1620 {
1621 
1622     return
1623         floatXToFloat64(
1624             floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1625 
1626 }
1627 
slow_float64_sub(float64 a,float64 b)1628 float64 slow_float64_sub( float64 a, float64 b )
1629 {
1630 
1631     b ^= LIT64( 0x8000000000000000 );
1632     return
1633         floatXToFloat64(
1634             floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1635 
1636 }
1637 
slow_float64_mul(float64 a,float64 b)1638 float64 slow_float64_mul( float64 a, float64 b )
1639 {
1640 
1641     return
1642         floatXToFloat64(
1643             floatXMul( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1644 
1645 }
1646 
slow_float64_div(float64 a,float64 b)1647 float64 slow_float64_div( float64 a, float64 b )
1648 {
1649 
1650     return
1651         floatXToFloat64(
1652             floatXDiv( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1653 
1654 }
1655 
slow_float64_rem(float64 a,float64 b)1656 float64 slow_float64_rem( float64 a, float64 b )
1657 {
1658 
1659     return
1660         floatXToFloat64(
1661             floatXRem( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1662 
1663 }
1664 
slow_float64_sqrt(float64 a)1665 float64 slow_float64_sqrt( float64 a )
1666 {
1667 
1668     return floatXToFloat64( floatXSqrt( float64ToFloatX( a ) ) );
1669 
1670 }
1671 
slow_float64_eq(float64 a,float64 b)1672 flag slow_float64_eq( float64 a, float64 b )
1673 {
1674 
1675     return floatXEq( float64ToFloatX( a ), float64ToFloatX( b ) );
1676 
1677 }
1678 
slow_float64_le(float64 a,float64 b)1679 flag slow_float64_le( float64 a, float64 b )
1680 {
1681     floatX ax, bx;
1682 
1683     ax = float64ToFloatX( a );
1684     bx = float64ToFloatX( b );
1685     if ( ax.isNaN || bx.isNaN ) {
1686         slow_float_exception_flags |= float_flag_invalid;
1687     }
1688     return floatXLe( ax, bx );
1689 
1690 }
1691 
slow_float64_lt(float64 a,float64 b)1692 flag slow_float64_lt( float64 a, float64 b )
1693 {
1694     floatX ax, bx;
1695 
1696     ax = float64ToFloatX( a );
1697     bx = float64ToFloatX( b );
1698     if ( ax.isNaN || bx.isNaN ) {
1699         slow_float_exception_flags |= float_flag_invalid;
1700     }
1701     return floatXLt( ax, bx );
1702 
1703 }
1704 
slow_float64_eq_signaling(float64 a,float64 b)1705 flag slow_float64_eq_signaling( float64 a, float64 b )
1706 {
1707     floatX ax, bx;
1708 
1709     ax = float64ToFloatX( a );
1710     bx = float64ToFloatX( b );
1711     if ( ax.isNaN || bx.isNaN ) {
1712         slow_float_exception_flags |= float_flag_invalid;
1713     }
1714     return floatXEq( ax, bx );
1715 
1716 }
1717 
slow_float64_le_quiet(float64 a,float64 b)1718 flag slow_float64_le_quiet( float64 a, float64 b )
1719 {
1720 
1721     return floatXLe( float64ToFloatX( a ), float64ToFloatX( b ) );
1722 
1723 }
1724 
slow_float64_lt_quiet(float64 a,float64 b)1725 flag slow_float64_lt_quiet( float64 a, float64 b )
1726 {
1727 
1728     return floatXLt( float64ToFloatX( a ), float64ToFloatX( b ) );
1729 
1730 }
1731 
1732 #ifdef FLOATX80
1733 
slow_floatx80_to_int32(floatx80 a)1734 int32 slow_floatx80_to_int32( floatx80 a )
1735 {
1736 
1737     return floatXToInt32( floatx80ToFloatX( a ) );
1738 
1739 }
1740 
slow_floatx80_to_int32_round_to_zero(floatx80 a)1741 int32 slow_floatx80_to_int32_round_to_zero( floatx80 a )
1742 {
1743     int8 savedRoundingMode;
1744     int32 z;
1745 
1746     savedRoundingMode = slow_float_rounding_mode;
1747     slow_float_rounding_mode = float_round_to_zero;
1748     z = floatXToInt32( floatx80ToFloatX( a ) );
1749     slow_float_rounding_mode = savedRoundingMode;
1750     return z;
1751 
1752 }
1753 
slow_floatx80_to_int64(floatx80 a)1754 int64 slow_floatx80_to_int64( floatx80 a )
1755 {
1756 
1757     return floatXToInt64( floatx80ToFloatX( a ) );
1758 
1759 }
1760 
slow_floatx80_to_int64_round_to_zero(floatx80 a)1761 int64 slow_floatx80_to_int64_round_to_zero( floatx80 a )
1762 {
1763     int8 savedRoundingMode;
1764     int64 z;
1765 
1766     savedRoundingMode = slow_float_rounding_mode;
1767     slow_float_rounding_mode = float_round_to_zero;
1768     z = floatXToInt64( floatx80ToFloatX( a ) );
1769     slow_float_rounding_mode = savedRoundingMode;
1770     return z;
1771 
1772 }
1773 
slow_floatx80_to_float32(floatx80 a)1774 float32 slow_floatx80_to_float32( floatx80 a )
1775 {
1776 
1777     return floatXToFloat32( floatx80ToFloatX( a ) );
1778 
1779 }
1780 
slow_floatx80_to_float64(floatx80 a)1781 float64 slow_floatx80_to_float64( floatx80 a )
1782 {
1783 
1784     return floatXToFloat64( floatx80ToFloatX( a ) );
1785 
1786 }
1787 
1788 #ifdef FLOAT128
1789 
slow_floatx80_to_float128(floatx80 a)1790 float128 slow_floatx80_to_float128( floatx80 a )
1791 {
1792 
1793     return floatXToFloat128( floatx80ToFloatX( a ) );
1794 
1795 }
1796 
1797 #endif
1798 
slow_floatx80_round_to_int(floatx80 a)1799 floatx80 slow_floatx80_round_to_int( floatx80 a )
1800 {
1801 
1802     return floatXToFloatx80( floatXRoundToInt( floatx80ToFloatX( a ) ) );
1803 
1804 }
1805 
slow_floatx80_add(floatx80 a,floatx80 b)1806 floatx80 slow_floatx80_add( floatx80 a, floatx80 b )
1807 {
1808 
1809     return
1810         floatXToFloatx80(
1811             floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1812 
1813 }
1814 
slow_floatx80_sub(floatx80 a,floatx80 b)1815 floatx80 slow_floatx80_sub( floatx80 a, floatx80 b )
1816 {
1817 
1818     b.high ^= 0x8000;
1819     return
1820         floatXToFloatx80(
1821             floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1822 
1823 }
1824 
slow_floatx80_mul(floatx80 a,floatx80 b)1825 floatx80 slow_floatx80_mul( floatx80 a, floatx80 b )
1826 {
1827 
1828     return
1829         floatXToFloatx80(
1830             floatXMul( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1831 
1832 }
1833 
slow_floatx80_div(floatx80 a,floatx80 b)1834 floatx80 slow_floatx80_div( floatx80 a, floatx80 b )
1835 {
1836 
1837     return
1838         floatXToFloatx80(
1839             floatXDiv( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1840 
1841 }
1842 
slow_floatx80_rem(floatx80 a,floatx80 b)1843 floatx80 slow_floatx80_rem( floatx80 a, floatx80 b )
1844 {
1845 
1846     return
1847         floatXToFloatx80(
1848             floatXRem( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1849 
1850 }
1851 
slow_floatx80_sqrt(floatx80 a)1852 floatx80 slow_floatx80_sqrt( floatx80 a )
1853 {
1854 
1855     return floatXToFloatx80( floatXSqrt( floatx80ToFloatX( a ) ) );
1856 
1857 }
1858 
slow_floatx80_eq(floatx80 a,floatx80 b)1859 flag slow_floatx80_eq( floatx80 a, floatx80 b )
1860 {
1861 
1862     return floatXEq( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
1863 
1864 }
1865 
slow_floatx80_le(floatx80 a,floatx80 b)1866 flag slow_floatx80_le( floatx80 a, floatx80 b )
1867 {
1868     floatX ax, bx;
1869 
1870     ax = floatx80ToFloatX( a );
1871     bx = floatx80ToFloatX( b );
1872     if ( ax.isNaN || bx.isNaN ) {
1873         slow_float_exception_flags |= float_flag_invalid;
1874     }
1875     return floatXLe( ax, bx );
1876 
1877 }
1878 
slow_floatx80_lt(floatx80 a,floatx80 b)1879 flag slow_floatx80_lt( floatx80 a, floatx80 b )
1880 {
1881     floatX ax, bx;
1882 
1883     ax = floatx80ToFloatX( a );
1884     bx = floatx80ToFloatX( b );
1885     if ( ax.isNaN || bx.isNaN ) {
1886         slow_float_exception_flags |= float_flag_invalid;
1887     }
1888     return floatXLt( ax, bx );
1889 
1890 }
1891 
slow_floatx80_eq_signaling(floatx80 a,floatx80 b)1892 flag slow_floatx80_eq_signaling( floatx80 a, floatx80 b )
1893 {
1894     floatX ax, bx;
1895 
1896     ax = floatx80ToFloatX( a );
1897     bx = floatx80ToFloatX( b );
1898     if ( ax.isNaN || bx.isNaN ) {
1899         slow_float_exception_flags |= float_flag_invalid;
1900     }
1901     return floatXEq( ax, bx );
1902 
1903 }
1904 
slow_floatx80_le_quiet(floatx80 a,floatx80 b)1905 flag slow_floatx80_le_quiet( floatx80 a, floatx80 b )
1906 {
1907 
1908     return floatXLe( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
1909 
1910 }
1911 
slow_floatx80_lt_quiet(floatx80 a,floatx80 b)1912 flag slow_floatx80_lt_quiet( floatx80 a, floatx80 b )
1913 {
1914 
1915     return floatXLt( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
1916 
1917 }
1918 
1919 #endif
1920 
1921 #ifdef FLOAT128
1922 
slow_float128_to_int32(float128 a)1923 int32 slow_float128_to_int32( float128 a )
1924 {
1925 
1926     return floatXToInt32( float128ToFloatX( a ) );
1927 
1928 }
1929 
slow_float128_to_int32_round_to_zero(float128 a)1930 int32 slow_float128_to_int32_round_to_zero( float128 a )
1931 {
1932     int8 savedRoundingMode;
1933     int32 z;
1934 
1935     savedRoundingMode = slow_float_rounding_mode;
1936     slow_float_rounding_mode = float_round_to_zero;
1937     z = floatXToInt32( float128ToFloatX( a ) );
1938     slow_float_rounding_mode = savedRoundingMode;
1939     return z;
1940 
1941 }
1942 
slow_float128_to_int64(float128 a)1943 int64 slow_float128_to_int64( float128 a )
1944 {
1945 
1946     return floatXToInt64( float128ToFloatX( a ) );
1947 
1948 }
1949 
slow_float128_to_int64_round_to_zero(float128 a)1950 int64 slow_float128_to_int64_round_to_zero( float128 a )
1951 {
1952     int8 savedRoundingMode;
1953     int64 z;
1954 
1955     savedRoundingMode = slow_float_rounding_mode;
1956     slow_float_rounding_mode = float_round_to_zero;
1957     z = floatXToInt64( float128ToFloatX( a ) );
1958     slow_float_rounding_mode = savedRoundingMode;
1959     return z;
1960 
1961 }
1962 
slow_float128_to_float32(float128 a)1963 float32 slow_float128_to_float32( float128 a )
1964 {
1965 
1966     return floatXToFloat32( float128ToFloatX( a ) );
1967 
1968 }
1969 
slow_float128_to_float64(float128 a)1970 float64 slow_float128_to_float64( float128 a )
1971 {
1972 
1973     return floatXToFloat64( float128ToFloatX( a ) );
1974 
1975 }
1976 
1977 #ifdef FLOATX80
1978 
slow_float128_to_floatx80(float128 a)1979 floatx80 slow_float128_to_floatx80( float128 a )
1980 {
1981 
1982     return floatXToFloatx80( float128ToFloatX( a ) );
1983 
1984 }
1985 
1986 #endif
1987 
slow_float128_round_to_int(float128 a)1988 float128 slow_float128_round_to_int( float128 a )
1989 {
1990 
1991     return floatXToFloat128( floatXRoundToInt( float128ToFloatX( a ) ) );
1992 
1993 }
1994 
slow_float128_add(float128 a,float128 b)1995 float128 slow_float128_add( float128 a, float128 b )
1996 {
1997 
1998     return
1999         floatXToFloat128(
2000             floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2001 
2002 }
2003 
slow_float128_sub(float128 a,float128 b)2004 float128 slow_float128_sub( float128 a, float128 b )
2005 {
2006 
2007     b.high ^= LIT64( 0x8000000000000000 );
2008     return
2009         floatXToFloat128(
2010             floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2011 
2012 }
2013 
slow_float128_mul(float128 a,float128 b)2014 float128 slow_float128_mul( float128 a, float128 b )
2015 {
2016 
2017     return
2018         floatXToFloat128(
2019             floatXMul( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2020 
2021 }
2022 
slow_float128_div(float128 a,float128 b)2023 float128 slow_float128_div( float128 a, float128 b )
2024 {
2025 
2026     return
2027         floatXToFloat128(
2028             floatXDiv( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2029 
2030 }
2031 
slow_float128_rem(float128 a,float128 b)2032 float128 slow_float128_rem( float128 a, float128 b )
2033 {
2034 
2035     return
2036         floatXToFloat128(
2037             floatXRem( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2038 
2039 }
2040 
slow_float128_sqrt(float128 a)2041 float128 slow_float128_sqrt( float128 a )
2042 {
2043 
2044     return floatXToFloat128( floatXSqrt( float128ToFloatX( a ) ) );
2045 
2046 }
2047 
slow_float128_eq(float128 a,float128 b)2048 flag slow_float128_eq( float128 a, float128 b )
2049 {
2050 
2051     return floatXEq( float128ToFloatX( a ), float128ToFloatX( b ) );
2052 
2053 }
2054 
slow_float128_le(float128 a,float128 b)2055 flag slow_float128_le( float128 a, float128 b )
2056 {
2057     floatX ax, bx;
2058 
2059     ax = float128ToFloatX( a );
2060     bx = float128ToFloatX( b );
2061     if ( ax.isNaN || bx.isNaN ) {
2062         slow_float_exception_flags |= float_flag_invalid;
2063     }
2064     return floatXLe( ax, bx );
2065 
2066 }
2067 
slow_float128_lt(float128 a,float128 b)2068 flag slow_float128_lt( float128 a, float128 b )
2069 {
2070     floatX ax, bx;
2071 
2072     ax = float128ToFloatX( a );
2073     bx = float128ToFloatX( b );
2074     if ( ax.isNaN || bx.isNaN ) {
2075         slow_float_exception_flags |= float_flag_invalid;
2076     }
2077     return floatXLt( ax, bx );
2078 
2079 }
2080 
slow_float128_eq_signaling(float128 a,float128 b)2081 flag slow_float128_eq_signaling( float128 a, float128 b )
2082 {
2083     floatX ax, bx;
2084 
2085     ax = float128ToFloatX( a );
2086     bx = float128ToFloatX( b );
2087     if ( ax.isNaN || bx.isNaN ) {
2088         slow_float_exception_flags |= float_flag_invalid;
2089     }
2090     return floatXEq( ax, bx );
2091 
2092 }
2093 
slow_float128_le_quiet(float128 a,float128 b)2094 flag slow_float128_le_quiet( float128 a, float128 b )
2095 {
2096 
2097     return floatXLe( float128ToFloatX( a ), float128ToFloatX( b ) );
2098 
2099 }
2100 
slow_float128_lt_quiet(float128 a,float128 b)2101 flag slow_float128_lt_quiet( float128 a, float128 b )
2102 {
2103 
2104     return floatXLt( float128ToFloatX( a ), float128ToFloatX( b ) );
2105 
2106 }
2107 
2108 #endif
2109 
2110