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 if (snan_bit_is_one(status)) {
499
500
501
502
503 if (infzero) {
504 float_raise(float_flag_invalid, status);
505 return 3;
506 }
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
524
525
526 if (infzero) {
527 float_raise(float_flag_invalid, status);
528 return 2;
529 }
530
531 if (is_snan(c_cls)) {
532 return 2;
533 } else if (is_snan(a_cls)) {
534 return 0;
535 } else if (is_snan(b_cls)) {
536 return 1;
537 } else if (is_qnan(c_cls)) {
538 return 2;
539 } else if (is_qnan(a_cls)) {
540 return 0;
541 } else {
542 return 1;
543 }
544 }
545#elif defined(TARGET_PPC)
546
547
548
549
550 if (infzero) {
551 float_raise(float_flag_invalid, status);
552 return 2;
553 }
554
555
556
557
558 if (is_nan(a_cls)) {
559 return 0;
560 } else if (is_nan(c_cls)) {
561 return 2;
562 } else {
563 return 1;
564 }
565#else
566
567
568
569 if (is_nan(a_cls)) {
570 return 0;
571 } else if (is_nan(b_cls)) {
572 return 1;
573 } else {
574 return 2;
575 }
576#endif
577}
578
579
580
581
582
583
584
585static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status)
586{
587 flag aIsLargerSignificand;
588 uint32_t av, bv;
589 FloatClass a_cls, b_cls;
590
591
592 a_cls = (!float32_is_any_nan(a)
593 ? float_class_normal
594 : float32_is_signaling_nan(a, status)
595 ? float_class_snan
596 : float_class_qnan);
597 b_cls = (!float32_is_any_nan(b)
598 ? float_class_normal
599 : float32_is_signaling_nan(b, status)
600 ? float_class_snan
601 : float_class_qnan);
602
603 av = float32_val(a);
604 bv = float32_val(b);
605
606 if (is_snan(a_cls) || is_snan(b_cls)) {
607 float_raise(float_flag_invalid, status);
608 }
609
610 if (status->default_nan_mode) {
611 return float32_default_nan(status);
612 }
613
614 if ((uint32_t)(av << 1) < (uint32_t)(bv << 1)) {
615 aIsLargerSignificand = 0;
616 } else if ((uint32_t)(bv << 1) < (uint32_t)(av << 1)) {
617 aIsLargerSignificand = 1;
618 } else {
619 aIsLargerSignificand = (av < bv) ? 1 : 0;
620 }
621
622 if (pickNaN(a_cls, b_cls, aIsLargerSignificand)) {
623 if (is_snan(b_cls)) {
624 return float32_silence_nan(b, status);
625 }
626 return b;
627 } else {
628 if (is_snan(a_cls)) {
629 return float32_silence_nan(a, status);
630 }
631 return a;
632 }
633}
634
635
636
637
638
639
640int float64_is_quiet_nan(float64 a_, float_status *status)
641{
642#ifdef NO_SIGNALING_NANS
643 return float64_is_any_nan(a_);
644#else
645 uint64_t a = float64_val(a_);
646 if (snan_bit_is_one(status)) {
647 return (((a >> 51) & 0xFFF) == 0xFFE)
648 && (a & 0x0007FFFFFFFFFFFFULL);
649 } else {
650 return ((a << 1) >= 0xFFF0000000000000ULL);
651 }
652#endif
653}
654
655
656
657
658
659
660int float64_is_signaling_nan(float64 a_, float_status *status)
661{
662#ifdef NO_SIGNALING_NANS
663 return 0;
664#else
665 uint64_t a = float64_val(a_);
666 if (snan_bit_is_one(status)) {
667 return ((a << 1) >= 0xFFF0000000000000ULL);
668 } else {
669 return (((a >> 51) & 0xFFF) == 0xFFE)
670 && (a & LIT64(0x0007FFFFFFFFFFFF));
671 }
672#endif
673}
674
675
676
677
678
679
680
681static commonNaNT float64ToCommonNaN(float64 a, float_status *status)
682{
683 commonNaNT z;
684
685 if (float64_is_signaling_nan(a, status)) {
686 float_raise(float_flag_invalid, status);
687 }
688 z.sign = float64_val(a) >> 63;
689 z.low = 0;
690 z.high = float64_val(a) << 12;
691 return z;
692}
693
694
695
696
697
698
699static float64 commonNaNToFloat64(commonNaNT a, float_status *status)
700{
701 uint64_t mantissa = a.high >> 12;
702
703 if (status->default_nan_mode) {
704 return float64_default_nan(status);
705 }
706
707 if (mantissa) {
708 return make_float64(
709 (((uint64_t) a.sign) << 63)
710 | LIT64(0x7FF0000000000000)
711 | (a.high >> 12));
712 } else {
713 return float64_default_nan(status);
714 }
715}
716
717
718
719
720
721
722
723static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status)
724{
725 flag aIsLargerSignificand;
726 uint64_t av, bv;
727 FloatClass a_cls, b_cls;
728
729
730 a_cls = (!float64_is_any_nan(a)
731 ? float_class_normal
732 : float64_is_signaling_nan(a, status)
733 ? float_class_snan
734 : float_class_qnan);
735 b_cls = (!float64_is_any_nan(b)
736 ? float_class_normal
737 : float64_is_signaling_nan(b, status)
738 ? float_class_snan
739 : float_class_qnan);
740
741 av = float64_val(a);
742 bv = float64_val(b);
743
744 if (is_snan(a_cls) || is_snan(b_cls)) {
745 float_raise(float_flag_invalid, status);
746 }
747
748 if (status->default_nan_mode) {
749 return float64_default_nan(status);
750 }
751
752 if ((uint64_t)(av << 1) < (uint64_t)(bv << 1)) {
753 aIsLargerSignificand = 0;
754 } else if ((uint64_t)(bv << 1) < (uint64_t)(av << 1)) {
755 aIsLargerSignificand = 1;
756 } else {
757 aIsLargerSignificand = (av < bv) ? 1 : 0;
758 }
759
760 if (pickNaN(a_cls, b_cls, aIsLargerSignificand)) {
761 if (is_snan(b_cls)) {
762 return float64_silence_nan(b, status);
763 }
764 return b;
765 } else {
766 if (is_snan(a_cls)) {
767 return float64_silence_nan(a, status);
768 }
769 return a;
770 }
771}
772
773
774
775
776
777
778
779int floatx80_is_quiet_nan(floatx80 a, float_status *status)
780{
781#ifdef NO_SIGNALING_NANS
782 return floatx80_is_any_nan(a);
783#else
784 if (snan_bit_is_one(status)) {
785 uint64_t aLow;
786
787 aLow = a.low & ~0x4000000000000000ULL;
788 return ((a.high & 0x7FFF) == 0x7FFF)
789 && (aLow << 1)
790 && (a.low == aLow);
791 } else {
792 return ((a.high & 0x7FFF) == 0x7FFF)
793 && (LIT64(0x8000000000000000) <= ((uint64_t)(a.low << 1)));
794 }
795#endif
796}
797
798
799
800
801
802
803
804int floatx80_is_signaling_nan(floatx80 a, float_status *status)
805{
806#ifdef NO_SIGNALING_NANS
807 return 0;
808#else
809 if (snan_bit_is_one(status)) {
810 return ((a.high & 0x7FFF) == 0x7FFF)
811 && ((a.low << 1) >= 0x8000000000000000ULL);
812 } else {
813 uint64_t aLow;
814
815 aLow = a.low & ~LIT64(0x4000000000000000);
816 return ((a.high & 0x7FFF) == 0x7FFF)
817 && (uint64_t)(aLow << 1)
818 && (a.low == aLow);
819 }
820#endif
821}
822
823
824
825
826
827
828floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
829{
830
831 assert(!snan_bit_is_one(status));
832 a.low |= LIT64(0xC000000000000000);
833 return a;
834}
835
836
837
838
839
840
841
842static commonNaNT floatx80ToCommonNaN(floatx80 a, float_status *status)
843{
844 floatx80 dflt;
845 commonNaNT z;
846
847 if (floatx80_is_signaling_nan(a, status)) {
848 float_raise(float_flag_invalid, status);
849 }
850 if (a.low >> 63) {
851 z.sign = a.high >> 15;
852 z.low = 0;
853 z.high = a.low << 1;
854 } else {
855 dflt = floatx80_default_nan(status);
856 z.sign = dflt.high >> 15;
857 z.low = 0;
858 z.high = dflt.low << 1;
859 }
860 return z;
861}
862
863
864
865
866
867
868static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status)
869{
870 floatx80 z;
871
872 if (status->default_nan_mode) {
873 return floatx80_default_nan(status);
874 }
875
876 if (a.high >> 1) {
877 z.low = LIT64(0x8000000000000000) | a.high >> 1;
878 z.high = (((uint16_t)a.sign) << 15) | 0x7FFF;
879 } else {
880 z = floatx80_default_nan(status);
881 }
882 return z;
883}
884
885
886
887
888
889
890
891floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
892{
893 flag aIsLargerSignificand;
894 FloatClass a_cls, b_cls;
895
896
897 a_cls = (!floatx80_is_any_nan(a)
898 ? float_class_normal
899 : floatx80_is_signaling_nan(a, status)
900 ? float_class_snan
901 : float_class_qnan);
902 b_cls = (!floatx80_is_any_nan(b)
903 ? float_class_normal
904 : floatx80_is_signaling_nan(b, status)
905 ? float_class_snan
906 : float_class_qnan);
907
908 if (is_snan(a_cls) || is_snan(b_cls)) {
909 float_raise(float_flag_invalid, status);
910 }
911
912 if (status->default_nan_mode) {
913 return floatx80_default_nan(status);
914 }
915
916 if (a.low < b.low) {
917 aIsLargerSignificand = 0;
918 } else if (b.low < a.low) {
919 aIsLargerSignificand = 1;
920 } else {
921 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
922 }
923
924 if (pickNaN(a_cls, b_cls, aIsLargerSignificand)) {
925 if (is_snan(b_cls)) {
926 return floatx80_silence_nan(b, status);
927 }
928 return b;
929 } else {
930 if (is_snan(a_cls)) {
931 return floatx80_silence_nan(a, status);
932 }
933 return a;
934 }
935}
936
937
938
939
940
941
942int float128_is_quiet_nan(float128 a, float_status *status)
943{
944#ifdef NO_SIGNALING_NANS
945 return float128_is_any_nan(a);
946#else
947 if (snan_bit_is_one(status)) {
948 return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
949 && (a.low || (a.high & 0x00007FFFFFFFFFFFULL));
950 } else {
951 return ((a.high << 1) >= 0xFFFF000000000000ULL)
952 && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
953 }
954#endif
955}
956
957
958
959
960
961
962int float128_is_signaling_nan(float128 a, float_status *status)
963{
964#ifdef NO_SIGNALING_NANS
965 return 0;
966#else
967 if (snan_bit_is_one(status)) {
968 return ((a.high << 1) >= 0xFFFF000000000000ULL)
969 && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
970 } else {
971 return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
972 && (a.low || (a.high & LIT64(0x00007FFFFFFFFFFF)));
973 }
974#endif
975}
976
977
978
979
980
981
982float128 float128_silence_nan(float128 a, float_status *status)
983{
984#ifdef NO_SIGNALING_NANS
985 g_assert_not_reached();
986#else
987 if (snan_bit_is_one(status)) {
988 return float128_default_nan(status);
989 } else {
990 a.high |= LIT64(0x0000800000000000);
991 return a;
992 }
993#endif
994}
995
996
997
998
999
1000
1001
1002static commonNaNT float128ToCommonNaN(float128 a, float_status *status)
1003{
1004 commonNaNT z;
1005
1006 if (float128_is_signaling_nan(a, status)) {
1007 float_raise(float_flag_invalid, status);
1008 }
1009 z.sign = a.high >> 63;
1010 shortShift128Left(a.high, a.low, 16, &z.high, &z.low);
1011 return z;
1012}
1013
1014
1015
1016
1017
1018
1019static float128 commonNaNToFloat128(commonNaNT a, float_status *status)
1020{
1021 float128 z;
1022
1023 if (status->default_nan_mode) {
1024 return float128_default_nan(status);
1025 }
1026
1027 shift128Right(a.high, a.low, 16, &z.high, &z.low);
1028 z.high |= (((uint64_t)a.sign) << 63) | LIT64(0x7FFF000000000000);
1029 return z;
1030}
1031
1032
1033
1034
1035
1036
1037
1038static float128 propagateFloat128NaN(float128 a, float128 b,
1039 float_status *status)
1040{
1041 flag aIsLargerSignificand;
1042 FloatClass a_cls, b_cls;
1043
1044
1045 a_cls = (!float128_is_any_nan(a)
1046 ? float_class_normal
1047 : float128_is_signaling_nan(a, status)
1048 ? float_class_snan
1049 : float_class_qnan);
1050 b_cls = (!float128_is_any_nan(b)
1051 ? float_class_normal
1052 : float128_is_signaling_nan(b, status)
1053 ? float_class_snan
1054 : float_class_qnan);
1055
1056 if (is_snan(a_cls) || is_snan(b_cls)) {
1057 float_raise(float_flag_invalid, status);
1058 }
1059
1060 if (status->default_nan_mode) {
1061 return float128_default_nan(status);
1062 }
1063
1064 if (lt128(a.high << 1, a.low, b.high << 1, b.low)) {
1065 aIsLargerSignificand = 0;
1066 } else if (lt128(b.high << 1, b.low, a.high << 1, a.low)) {
1067 aIsLargerSignificand = 1;
1068 } else {
1069 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
1070 }
1071
1072 if (pickNaN(a_cls, b_cls, aIsLargerSignificand)) {
1073 if (is_snan(b_cls)) {
1074 return float128_silence_nan(b, status);
1075 }
1076 return b;
1077 } else {
1078 if (is_snan(a_cls)) {
1079 return float128_silence_nan(a, status);
1080 }
1081 return a;
1082 }
1083}
1084