1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85#if defined(TARGET_XTENSA)
86#define NO_SIGNALING_NANS 1
87#endif
88
89
90
91
92
93
94
95
96static inline flag snan_bit_is_one(float_status *status)
97{
98#if defined(TARGET_MIPS)
99 return status->snan_bit_is_one;
100#elif defined(TARGET_HPPA) || defined(TARGET_UNICORE32) || defined(TARGET_SH4)
101 return 1;
102#else
103 return 0;
104#endif
105}
106
107
108
109
110
111
112static bool parts_is_snan_frac(uint64_t frac, float_status *status)
113{
114#ifdef NO_SIGNALING_NANS
115 return false;
116#else
117 flag msb = extract64(frac, DECOMPOSED_BINARY_POINT - 1, 1);
118 return msb == snan_bit_is_one(status);
119#endif
120}
121
122
123
124
125
126static FloatParts parts_default_nan(float_status *status)
127{
128 bool sign = 0;
129 uint64_t frac;
130
131#if defined(TARGET_SPARC) || defined(TARGET_M68K)
132
133 frac = (1ULL << DECOMPOSED_BINARY_POINT) - 1;
134#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
135 || defined(TARGET_MICROBLAZE)
136
137 frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
138 sign = 1;
139#elif defined(TARGET_HPPA)
140
141 frac = 1ULL << (DECOMPOSED_BINARY_POINT - 2);
142#else
143
144
145
146
147
148
149 if (snan_bit_is_one(status)) {
150
151 frac = (1ULL << (DECOMPOSED_BINARY_POINT - 1)) - 1;
152 } else {
153
154 frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
155 }
156#endif
157
158 return (FloatParts) {
159 .cls = float_class_qnan,
160 .sign = sign,
161 .exp = INT_MAX,
162 .frac = frac
163 };
164}
165
166
167
168
169
170
171static FloatParts parts_silence_nan(FloatParts a, float_status *status)
172{
173#ifdef NO_SIGNALING_NANS
174 g_assert_not_reached();
175#elif defined(TARGET_HPPA)
176 a.frac &= ~(1ULL << (DECOMPOSED_BINARY_POINT - 1));
177 a.frac |= 1ULL << (DECOMPOSED_BINARY_POINT - 2);
178#else
179 if (snan_bit_is_one(status)) {
180 return parts_default_nan(status);
181 } else {
182 a.frac |= 1ULL << (DECOMPOSED_BINARY_POINT - 1);
183 }
184#endif
185 a.cls = float_class_qnan;
186 return a;
187}
188
189
190
191
192floatx80 floatx80_default_nan(float_status *status)
193{
194 floatx80 r;
195
196
197 assert(!snan_bit_is_one(status));
198#if defined(TARGET_M68K)
199 r.low = LIT64(0xFFFFFFFFFFFFFFFF);
200 r.high = 0x7FFF;
201#else
202
203 r.low = LIT64(0xC000000000000000);
204 r.high = 0xFFFF;
205#endif
206 return r;
207}
208
209
210
211
212
213#define floatx80_infinity_high 0x7FFF
214#if defined(TARGET_M68K)
215#define floatx80_infinity_low LIT64(0x0000000000000000)
216#else
217#define floatx80_infinity_low LIT64(0x8000000000000000)
218#endif
219
220const floatx80 floatx80_infinity
221 = make_floatx80_init(floatx80_infinity_high, floatx80_infinity_low);
222
223
224
225
226
227
228
229
230void float_raise(uint8_t flags, float_status *status)
231{
232 status->float_exception_flags |= flags;
233}
234
235
236
237
238typedef struct {
239 flag sign;
240 uint64_t high, low;
241} commonNaNT;
242
243
244
245
246
247
248int float16_is_quiet_nan(float16 a_, float_status *status)
249{
250#ifdef NO_SIGNALING_NANS
251 return float16_is_any_nan(a_);
252#else
253 uint16_t a = float16_val(a_);
254 if (snan_bit_is_one(status)) {
255 return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
256 } else {
257 return ((a & ~0x8000) >= 0x7C80);
258 }
259#endif
260}
261
262
263
264
265
266
267int float16_is_signaling_nan(float16 a_, float_status *status)
268{
269#ifdef NO_SIGNALING_NANS
270 return 0;
271#else
272 uint16_t a = float16_val(a_);
273 if (snan_bit_is_one(status)) {
274 return ((a & ~0x8000) >= 0x7C80);
275 } else {
276 return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
277 }
278#endif
279}
280
281
282
283
284
285
286int float32_is_quiet_nan(float32 a_, float_status *status)
287{
288#ifdef NO_SIGNALING_NANS
289 return float32_is_any_nan(a_);
290#else
291 uint32_t a = float32_val(a_);
292 if (snan_bit_is_one(status)) {
293 return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
294 } else {
295 return ((uint32_t)(a << 1) >= 0xFF800000);
296 }
297#endif
298}
299
300
301
302
303
304
305int float32_is_signaling_nan(float32 a_, float_status *status)
306{
307#ifdef NO_SIGNALING_NANS
308 return 0;
309#else
310 uint32_t a = float32_val(a_);
311 if (snan_bit_is_one(status)) {
312 return ((uint32_t)(a << 1) >= 0xFF800000);
313 } else {
314 return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
315 }
316#endif
317}
318
319
320
321
322
323
324
325static commonNaNT float32ToCommonNaN(float32 a, float_status *status)
326{
327 commonNaNT z;
328
329 if (float32_is_signaling_nan(a, status)) {
330 float_raise(float_flag_invalid, status);
331 }
332 z.sign = float32_val(a) >> 31;
333 z.low = 0;
334 z.high = ((uint64_t)float32_val(a)) << 41;
335 return z;
336}
337
338
339
340
341
342
343static float32 commonNaNToFloat32(commonNaNT a, float_status *status)
344{
345 uint32_t mantissa = a.high >> 41;
346
347 if (status->default_nan_mode) {
348 return float32_default_nan(status);
349 }
350
351 if (mantissa) {
352 return make_float32(
353 (((uint32_t)a.sign) << 31) | 0x7F800000 | (a.high >> 41));
354 } else {
355 return float32_default_nan(status);
356 }
357}
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376static int pickNaN(FloatClass a_cls, FloatClass b_cls,
377 flag aIsLargerSignificand)
378{
379#if defined(TARGET_ARM) || defined(TARGET_MIPS) || defined(TARGET_HPPA)
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401 if (is_snan(a_cls)) {
402 return 0;
403 } else if (is_snan(b_cls)) {
404 return 1;
405 } else if (is_qnan(a_cls)) {
406 return 0;
407 } else {
408 return 1;
409 }
410#elif defined(TARGET_PPC) || defined(TARGET_XTENSA) || defined(TARGET_M68K)
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430 if (is_nan(a_cls)) {
431 return 0;
432 } else {
433 return 1;
434 }
435#else
436
437
438
439
440
441
442
443
444
445
446 if (is_snan(a_cls)) {
447 if (is_snan(b_cls)) {
448 return aIsLargerSignificand ? 0 : 1;
449 }
450 return is_qnan(b_cls) ? 1 : 0;
451 } else if (is_qnan(a_cls)) {
452 if (is_snan(b_cls) || !is_qnan(b_cls)) {
453 return 0;
454 } else {
455 return aIsLargerSignificand ? 0 : 1;
456 }
457 } else {
458 return 1;
459 }
460#endif
461}
462
463
464
465
466
467
468
469static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
470 bool infzero, float_status *status)
471{
472#if defined(TARGET_ARM)
473
474
475
476 if (infzero && is_qnan(c_cls)) {
477 float_raise(float_flag_invalid, status);
478 return 3;
479 }
480
481
482
483
484 if (is_snan(c_cls)) {
485 return 2;
486 } else if (is_snan(a_cls)) {
487 return 0;
488 } else if (is_snan(b_cls)) {
489 return 1;
490 } else if (is_qnan(c_cls)) {
491 return 2;
492 } else if (is_qnan(a_cls)) {
493 return 0;
494 } else {
495 return 1;
496 }
497#elif defined(TARGET_MIPS)
498
499
500
501 if (infzero) {
502 float_raise(float_flag_invalid, status);
503 return 3;
504 }
505
506 if (snan_bit_is_one(status)) {
507
508 if (is_snan(a_cls)) {
509 return 0;
510 } else if (is_snan(b_cls)) {
511 return 1;
512 } else if (is_snan(c_cls)) {
513 return 2;
514 } else if (is_qnan(a_cls)) {
515 return 0;
516 } else if (is_qnan(b_cls)) {
517 return 1;
518 } else {
519 return 2;
520 }
521 } else {
522
523 if (is_snan(c_cls)) {
524 return 2;
525 } else if (is_snan(a_cls)) {
526 return 0;
527 } else if (is_snan(b_cls)) {
528 return 1;
529 } else if (is_qnan(c_cls)) {
530 return 2;
531 } else if (is_qnan(a_cls)) {
532 return 0;
533 } else {
534 return 1;
535 }
536 }
537#elif defined(TARGET_PPC)
538
539
540
541
542 if (infzero) {
543 float_raise(float_flag_invalid, status);
544 return 2;
545 }
546
547
548
549
550 if (is_nan(a_cls)) {
551 return 0;
552 } else if (is_nan(c_cls)) {
553 return 2;
554 } else {
555 return 1;
556 }
557#else
558
559
560
561 if (is_nan(a_cls)) {
562 return 0;
563 } else if (is_nan(b_cls)) {
564 return 1;
565 } else {
566 return 2;
567 }
568#endif
569}
570
571
572
573
574
575
576
577static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status)
578{
579 flag aIsLargerSignificand;
580 uint32_t av, bv;
581 FloatClass a_cls, b_cls;
582
583
584 a_cls = (!float32_is_any_nan(a)
585 ? float_class_normal
586 : float32_is_signaling_nan(a, status)
587 ? float_class_snan
588 : float_class_qnan);
589 b_cls = (!float32_is_any_nan(b)
590 ? float_class_normal
591 : float32_is_signaling_nan(b, status)
592 ? float_class_snan
593 : float_class_qnan);
594
595 av = float32_val(a);
596 bv = float32_val(b);
597
598 if (is_snan(a_cls) || is_snan(b_cls)) {
599 float_raise(float_flag_invalid, status);
600 }
601
602 if (status->default_nan_mode) {
603 return float32_default_nan(status);
604 }
605
606 if ((uint32_t)(av << 1) < (uint32_t)(bv << 1)) {
607 aIsLargerSignificand = 0;
608 } else if ((uint32_t)(bv << 1) < (uint32_t)(av << 1)) {
609 aIsLargerSignificand = 1;
610 } else {
611 aIsLargerSignificand = (av < bv) ? 1 : 0;
612 }
613
614 if (pickNaN(a_cls, b_cls, aIsLargerSignificand)) {
615 if (is_snan(b_cls)) {
616 return float32_silence_nan(b, status);
617 }
618 return b;
619 } else {
620 if (is_snan(a_cls)) {
621 return float32_silence_nan(a, status);
622 }
623 return a;
624 }
625}
626
627
628
629
630
631
632int float64_is_quiet_nan(float64 a_, float_status *status)
633{
634#ifdef NO_SIGNALING_NANS
635 return float64_is_any_nan(a_);
636#else
637 uint64_t a = float64_val(a_);
638 if (snan_bit_is_one(status)) {
639 return (((a >> 51) & 0xFFF) == 0xFFE)
640 && (a & 0x0007FFFFFFFFFFFFULL);
641 } else {
642 return ((a << 1) >= 0xFFF0000000000000ULL);
643 }
644#endif
645}
646
647
648
649
650
651
652int float64_is_signaling_nan(float64 a_, float_status *status)
653{
654#ifdef NO_SIGNALING_NANS
655 return 0;
656#else
657 uint64_t a = float64_val(a_);
658 if (snan_bit_is_one(status)) {
659 return ((a << 1) >= 0xFFF0000000000000ULL);
660 } else {
661 return (((a >> 51) & 0xFFF) == 0xFFE)
662 && (a & LIT64(0x0007FFFFFFFFFFFF));
663 }
664#endif
665}
666
667
668
669
670
671
672
673static commonNaNT float64ToCommonNaN(float64 a, float_status *status)
674{
675 commonNaNT z;
676
677 if (float64_is_signaling_nan(a, status)) {
678 float_raise(float_flag_invalid, status);
679 }
680 z.sign = float64_val(a) >> 63;
681 z.low = 0;
682 z.high = float64_val(a) << 12;
683 return z;
684}
685
686
687
688
689
690
691static float64 commonNaNToFloat64(commonNaNT a, float_status *status)
692{
693 uint64_t mantissa = a.high >> 12;
694
695 if (status->default_nan_mode) {
696 return float64_default_nan(status);
697 }
698
699 if (mantissa) {
700 return make_float64(
701 (((uint64_t) a.sign) << 63)
702 | LIT64(0x7FF0000000000000)
703 | (a.high >> 12));
704 } else {
705 return float64_default_nan(status);
706 }
707}
708
709
710
711
712
713
714
715static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status)
716{
717 flag aIsLargerSignificand;
718 uint64_t av, bv;
719 FloatClass a_cls, b_cls;
720
721
722 a_cls = (!float64_is_any_nan(a)
723 ? float_class_normal
724 : float64_is_signaling_nan(a, status)
725 ? float_class_snan
726 : float_class_qnan);
727 b_cls = (!float64_is_any_nan(b)
728 ? float_class_normal
729 : float64_is_signaling_nan(b, status)
730 ? float_class_snan
731 : float_class_qnan);
732
733 av = float64_val(a);
734 bv = float64_val(b);
735
736 if (is_snan(a_cls) || is_snan(b_cls)) {
737 float_raise(float_flag_invalid, status);
738 }
739
740 if (status->default_nan_mode) {
741 return float64_default_nan(status);
742 }
743
744 if ((uint64_t)(av << 1) < (uint64_t)(bv << 1)) {
745 aIsLargerSignificand = 0;
746 } else if ((uint64_t)(bv << 1) < (uint64_t)(av << 1)) {
747 aIsLargerSignificand = 1;
748 } else {
749 aIsLargerSignificand = (av < bv) ? 1 : 0;
750 }
751
752 if (pickNaN(a_cls, b_cls, aIsLargerSignificand)) {
753 if (is_snan(b_cls)) {
754 return float64_silence_nan(b, status);
755 }
756 return b;
757 } else {
758 if (is_snan(a_cls)) {
759 return float64_silence_nan(a, status);
760 }
761 return a;
762 }
763}
764
765
766
767
768
769
770
771int floatx80_is_quiet_nan(floatx80 a, float_status *status)
772{
773#ifdef NO_SIGNALING_NANS
774 return floatx80_is_any_nan(a);
775#else
776 if (snan_bit_is_one(status)) {
777 uint64_t aLow;
778
779 aLow = a.low & ~0x4000000000000000ULL;
780 return ((a.high & 0x7FFF) == 0x7FFF)
781 && (aLow << 1)
782 && (a.low == aLow);
783 } else {
784 return ((a.high & 0x7FFF) == 0x7FFF)
785 && (LIT64(0x8000000000000000) <= ((uint64_t)(a.low << 1)));
786 }
787#endif
788}
789
790
791
792
793
794
795
796int floatx80_is_signaling_nan(floatx80 a, float_status *status)
797{
798#ifdef NO_SIGNALING_NANS
799 return 0;
800#else
801 if (snan_bit_is_one(status)) {
802 return ((a.high & 0x7FFF) == 0x7FFF)
803 && ((a.low << 1) >= 0x8000000000000000ULL);
804 } else {
805 uint64_t aLow;
806
807 aLow = a.low & ~LIT64(0x4000000000000000);
808 return ((a.high & 0x7FFF) == 0x7FFF)
809 && (uint64_t)(aLow << 1)
810 && (a.low == aLow);
811 }
812#endif
813}
814
815
816
817
818
819
820floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
821{
822
823 assert(!snan_bit_is_one(status));
824 a.low |= LIT64(0xC000000000000000);
825 return a;
826}
827
828
829
830
831
832
833
834static commonNaNT floatx80ToCommonNaN(floatx80 a, float_status *status)
835{
836 floatx80 dflt;
837 commonNaNT z;
838
839 if (floatx80_is_signaling_nan(a, status)) {
840 float_raise(float_flag_invalid, status);
841 }
842 if (a.low >> 63) {
843 z.sign = a.high >> 15;
844 z.low = 0;
845 z.high = a.low << 1;
846 } else {
847 dflt = floatx80_default_nan(status);
848 z.sign = dflt.high >> 15;
849 z.low = 0;
850 z.high = dflt.low << 1;
851 }
852 return z;
853}
854
855
856
857
858
859
860static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status)
861{
862 floatx80 z;
863
864 if (status->default_nan_mode) {
865 return floatx80_default_nan(status);
866 }
867
868 if (a.high >> 1) {
869 z.low = LIT64(0x8000000000000000) | a.high >> 1;
870 z.high = (((uint16_t)a.sign) << 15) | 0x7FFF;
871 } else {
872 z = floatx80_default_nan(status);
873 }
874 return z;
875}
876
877
878
879
880
881
882
883floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
884{
885 flag aIsLargerSignificand;
886 FloatClass a_cls, b_cls;
887
888
889 a_cls = (!floatx80_is_any_nan(a)
890 ? float_class_normal
891 : floatx80_is_signaling_nan(a, status)
892 ? float_class_snan
893 : float_class_qnan);
894 b_cls = (!floatx80_is_any_nan(b)
895 ? float_class_normal
896 : floatx80_is_signaling_nan(b, status)
897 ? float_class_snan
898 : float_class_qnan);
899
900 if (is_snan(a_cls) || is_snan(b_cls)) {
901 float_raise(float_flag_invalid, status);
902 }
903
904 if (status->default_nan_mode) {
905 return floatx80_default_nan(status);
906 }
907
908 if (a.low < b.low) {
909 aIsLargerSignificand = 0;
910 } else if (b.low < a.low) {
911 aIsLargerSignificand = 1;
912 } else {
913 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
914 }
915
916 if (pickNaN(a_cls, b_cls, aIsLargerSignificand)) {
917 if (is_snan(b_cls)) {
918 return floatx80_silence_nan(b, status);
919 }
920 return b;
921 } else {
922 if (is_snan(a_cls)) {
923 return floatx80_silence_nan(a, status);
924 }
925 return a;
926 }
927}
928
929
930
931
932
933
934int float128_is_quiet_nan(float128 a, float_status *status)
935{
936#ifdef NO_SIGNALING_NANS
937 return float128_is_any_nan(a);
938#else
939 if (snan_bit_is_one(status)) {
940 return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
941 && (a.low || (a.high & 0x00007FFFFFFFFFFFULL));
942 } else {
943 return ((a.high << 1) >= 0xFFFF000000000000ULL)
944 && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
945 }
946#endif
947}
948
949
950
951
952
953
954int float128_is_signaling_nan(float128 a, float_status *status)
955{
956#ifdef NO_SIGNALING_NANS
957 return 0;
958#else
959 if (snan_bit_is_one(status)) {
960 return ((a.high << 1) >= 0xFFFF000000000000ULL)
961 && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
962 } else {
963 return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
964 && (a.low || (a.high & LIT64(0x00007FFFFFFFFFFF)));
965 }
966#endif
967}
968
969
970
971
972
973
974float128 float128_silence_nan(float128 a, float_status *status)
975{
976#ifdef NO_SIGNALING_NANS
977 g_assert_not_reached();
978#else
979 if (snan_bit_is_one(status)) {
980 return float128_default_nan(status);
981 } else {
982 a.high |= LIT64(0x0000800000000000);
983 return a;
984 }
985#endif
986}
987
988
989
990
991
992
993
994static commonNaNT float128ToCommonNaN(float128 a, float_status *status)
995{
996 commonNaNT z;
997
998 if (float128_is_signaling_nan(a, status)) {
999 float_raise(float_flag_invalid, status);
1000 }
1001 z.sign = a.high >> 63;
1002 shortShift128Left(a.high, a.low, 16, &z.high, &z.low);
1003 return z;
1004}
1005
1006
1007
1008
1009
1010
1011static float128 commonNaNToFloat128(commonNaNT a, float_status *status)
1012{
1013 float128 z;
1014
1015 if (status->default_nan_mode) {
1016 return float128_default_nan(status);
1017 }
1018
1019 shift128Right(a.high, a.low, 16, &z.high, &z.low);
1020 z.high |= (((uint64_t)a.sign) << 63) | LIT64(0x7FFF000000000000);
1021 return z;
1022}
1023
1024
1025
1026
1027
1028
1029
1030static float128 propagateFloat128NaN(float128 a, float128 b,
1031 float_status *status)
1032{
1033 flag aIsLargerSignificand;
1034 FloatClass a_cls, b_cls;
1035
1036
1037 a_cls = (!float128_is_any_nan(a)
1038 ? float_class_normal
1039 : float128_is_signaling_nan(a, status)
1040 ? float_class_snan
1041 : float_class_qnan);
1042 b_cls = (!float128_is_any_nan(b)
1043 ? float_class_normal
1044 : float128_is_signaling_nan(b, status)
1045 ? float_class_snan
1046 : float_class_qnan);
1047
1048 if (is_snan(a_cls) || is_snan(b_cls)) {
1049 float_raise(float_flag_invalid, status);
1050 }
1051
1052 if (status->default_nan_mode) {
1053 return float128_default_nan(status);
1054 }
1055
1056 if (lt128(a.high << 1, a.low, b.high << 1, b.low)) {
1057 aIsLargerSignificand = 0;
1058 } else if (lt128(b.high << 1, b.low, a.high << 1, a.low)) {
1059 aIsLargerSignificand = 1;
1060 } else {
1061 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
1062 }
1063
1064 if (pickNaN(a_cls, b_cls, aIsLargerSignificand)) {
1065 if (is_snan(b_cls)) {
1066 return float128_silence_nan(b, status);
1067 }
1068 return b;
1069 } else {
1070 if (is_snan(a_cls)) {
1071 return float128_silence_nan(a, status);
1072 }
1073 return a;
1074 }
1075}
1076