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