source: mainline/uspace/lib/softfloat/comparison.c@ 3212921

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3212921 was 3212921, checked in by Jakub Jermar <jakub@…>, 7 years ago

Add aeabi_fcmple

  • Property mode set to 100644
File size: 22.6 KB
Line 
1/*
2 * Copyright (c) 2005 Josef Cejka
3 * Copyright (c) 2011 Petr Koupy
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup softfloat
31 * @{
32 */
33/** @file Comparison functions.
34 */
35
36#include "comparison.h"
37#include "common.h"
38
39/**
40 * Determines whether the given float represents NaN (either signalling NaN or
41 * quiet NaN).
42 *
43 * @param f Single-precision float.
44 * @return 1 if float is NaN, 0 otherwise.
45 */
46int is_float32_nan(float32 f)
47{
48 /* NaN : exp = 0xff and nonzero fraction */
49 return ((f.parts.exp == 0xFF) && (f.parts.fraction));
50}
51
52/**
53 * Determines whether the given float represents NaN (either signalling NaN or
54 * quiet NaN).
55 *
56 * @param d Double-precision float.
57 * @return 1 if float is NaN, 0 otherwise.
58 */
59int is_float64_nan(float64 d)
60{
61 /* NaN : exp = 0x7ff and nonzero fraction */
62 return ((d.parts.exp == 0x7FF) && (d.parts.fraction));
63}
64
65/**
66 * Determines whether the given float represents NaN (either signalling NaN or
67 * quiet NaN).
68 *
69 * @param ld Quadruple-precision float.
70 * @return 1 if float is NaN, 0 otherwise.
71 */
72int is_float128_nan(float128 ld)
73{
74 /* NaN : exp = 0x7fff and nonzero fraction */
75 return ((ld.parts.exp == 0x7FF) &&
76 !eq128(ld.parts.frac_hi, ld.parts.frac_lo, 0x0ll, 0x0ll));
77}
78
79/**
80 * Determines whether the given float represents signalling NaN.
81 *
82 * @param f Single-precision float.
83 * @return 1 if float is signalling NaN, 0 otherwise.
84 */
85int is_float32_signan(float32 f)
86{
87 /* SigNaN : exp = 0xff and fraction = 0xxxxx..x (binary),
88 * where at least one x is nonzero */
89 return ((f.parts.exp == 0xFF) &&
90 (f.parts.fraction < 0x400000) && (f.parts.fraction));
91}
92
93/**
94 * Determines whether the given float represents signalling NaN.
95 *
96 * @param d Double-precision float.
97 * @return 1 if float is signalling NaN, 0 otherwise.
98 */
99int is_float64_signan(float64 d)
100{
101 /* SigNaN : exp = 0x7ff and fraction = 0xxxxx..x (binary),
102 * where at least one x is nonzero */
103 return ((d.parts.exp == 0x7FF) &&
104 (d.parts.fraction) && (d.parts.fraction < 0x8000000000000ll));
105}
106
107/**
108 * Determines whether the given float represents signalling NaN.
109 *
110 * @param ld Quadruple-precision float.
111 * @return 1 if float is signalling NaN, 0 otherwise.
112 */
113int is_float128_signan(float128 ld)
114{
115 /* SigNaN : exp = 0x7fff and fraction = 0xxxxx..x (binary),
116 * where at least one x is nonzero */
117 return ((ld.parts.exp == 0x7FFF) &&
118 (ld.parts.frac_hi || ld.parts.frac_lo) &&
119 lt128(ld.parts.frac_hi, ld.parts.frac_lo, 0x800000000000ll, 0x0ll));
120
121}
122
123/**
124 * Determines whether the given float represents positive or negative infinity.
125 *
126 * @param f Single-precision float.
127 * @return 1 if float is infinite, 0 otherwise.
128 */
129int is_float32_infinity(float32 f)
130{
131 /* NaN : exp = 0x7ff and zero fraction */
132 return ((f.parts.exp == 0xFF) && (f.parts.fraction == 0x0));
133}
134
135/**
136 * Determines whether the given float represents positive or negative infinity.
137 *
138 * @param d Double-precision float.
139 * @return 1 if float is infinite, 0 otherwise.
140 */
141int is_float64_infinity(float64 d)
142{
143 /* NaN : exp = 0x7ff and zero fraction */
144 return ((d.parts.exp == 0x7FF) && (d.parts.fraction == 0x0));
145}
146
147/**
148 * Determines whether the given float represents positive or negative infinity.
149 *
150 * @param ld Quadruple-precision float.
151 * @return 1 if float is infinite, 0 otherwise.
152 */
153int is_float128_infinity(float128 ld)
154{
155 /* NaN : exp = 0x7fff and zero fraction */
156 return ((ld.parts.exp == 0x7FFF) &&
157 eq128(ld.parts.frac_hi, ld.parts.frac_lo, 0x0ll, 0x0ll));
158}
159
160/**
161 * Determines whether the given float represents positive or negative zero.
162 *
163 * @param f Single-precision float.
164 * @return 1 if float is zero, 0 otherwise.
165 */
166int is_float32_zero(float32 f)
167{
168 return (((f.bin) & 0x7FFFFFFF) == 0);
169}
170
171/**
172 * Determines whether the given float represents positive or negative zero.
173 *
174 * @param d Double-precision float.
175 * @return 1 if float is zero, 0 otherwise.
176 */
177int is_float64_zero(float64 d)
178{
179 return (((d.bin) & 0x7FFFFFFFFFFFFFFFll) == 0);
180}
181
182/**
183 * Determines whether the given float represents positive or negative zero.
184 *
185 * @param ld Quadruple-precision float.
186 * @return 1 if float is zero, 0 otherwise.
187 */
188int is_float128_zero(float128 ld)
189{
190 uint64_t tmp_hi;
191 uint64_t tmp_lo;
192
193 and128(ld.bin.hi, ld.bin.lo,
194 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
195
196 return eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll);
197}
198
199/**
200 * Determine whether two floats are equal. NaNs are not recognized.
201 *
202 * @a First single-precision operand.
203 * @b Second single-precision operand.
204 * @return 1 if both floats are equal, 0 otherwise.
205 */
206int is_float32_eq(float32 a, float32 b)
207{
208 /* a equals to b or both are zeros (with any sign) */
209 return ((a.bin == b.bin) ||
210 (((a.bin | b.bin) & 0x7FFFFFFF) == 0));
211}
212
213/**
214 * Determine whether two floats are equal. NaNs are not recognized.
215 *
216 * @a First double-precision operand.
217 * @b Second double-precision operand.
218 * @return 1 if both floats are equal, 0 otherwise.
219 */
220int is_float64_eq(float64 a, float64 b)
221{
222 /* a equals to b or both are zeros (with any sign) */
223 return ((a.bin == b.bin) ||
224 (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0));
225}
226
227/**
228 * Determine whether two floats are equal. NaNs are not recognized.
229 *
230 * @a First quadruple-precision operand.
231 * @b Second quadruple-precision operand.
232 * @return 1 if both floats are equal, 0 otherwise.
233 */
234int is_float128_eq(float128 a, float128 b)
235{
236 uint64_t tmp_hi;
237 uint64_t tmp_lo;
238
239 /* both are zeros (with any sign) */
240 or128(a.bin.hi, a.bin.lo,
241 b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
242 and128(tmp_hi, tmp_lo,
243 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
244 int both_zero = eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll);
245
246 /* a equals to b */
247 int are_equal = eq128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
248
249 return are_equal || both_zero;
250}
251
252/**
253 * Lower-than comparison between two floats. NaNs are not recognized.
254 *
255 * @a First single-precision operand.
256 * @b Second single-precision operand.
257 * @return 1 if a is lower than b, 0 otherwise.
258 */
259int is_float32_lt(float32 a, float32 b)
260{
261 if (((a.bin | b.bin) & 0x7FFFFFFF) == 0) {
262 /* +- zeroes */
263 return 0;
264 }
265
266 if ((a.parts.sign) && (b.parts.sign)) {
267 /* if both are negative, smaller is that with greater binary value */
268 return (a.bin > b.bin);
269 }
270
271 /*
272 * lets negate signs - now will be positive numbers always
273 * bigger than negative (first bit will be set for unsigned
274 * integer comparison)
275 */
276 a.parts.sign = !a.parts.sign;
277 b.parts.sign = !b.parts.sign;
278 return (a.bin < b.bin);
279}
280
281/**
282 * Lower-than comparison between two floats. NaNs are not recognized.
283 *
284 * @a First double-precision operand.
285 * @b Second double-precision operand.
286 * @return 1 if a is lower than b, 0 otherwise.
287 */
288int is_float64_lt(float64 a, float64 b)
289{
290 if (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0) {
291 /* +- zeroes */
292 return 0;
293 }
294
295 if ((a.parts.sign) && (b.parts.sign)) {
296 /* if both are negative, smaller is that with greater binary value */
297 return (a.bin > b.bin);
298 }
299
300 /*
301 * lets negate signs - now will be positive numbers always
302 * bigger than negative (first bit will be set for unsigned
303 * integer comparison)
304 */
305 a.parts.sign = !a.parts.sign;
306 b.parts.sign = !b.parts.sign;
307 return (a.bin < b.bin);
308}
309
310/**
311 * Lower-than comparison between two floats. NaNs are not recognized.
312 *
313 * @a First quadruple-precision operand.
314 * @b Second quadruple-precision operand.
315 * @return 1 if a is lower than b, 0 otherwise.
316 */
317int is_float128_lt(float128 a, float128 b)
318{
319 uint64_t tmp_hi;
320 uint64_t tmp_lo;
321
322 or128(a.bin.hi, a.bin.lo,
323 b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
324 and128(tmp_hi, tmp_lo,
325 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
326 if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
327 /* +- zeroes */
328 return 0;
329 }
330
331 if ((a.parts.sign) && (b.parts.sign)) {
332 /* if both are negative, smaller is that with greater binary value */
333 return lt128(b.bin.hi, b.bin.lo, a.bin.hi, a.bin.lo);
334 }
335
336 /*
337 * lets negate signs - now will be positive numbers always
338 * bigger than negative (first bit will be set for unsigned
339 * integer comparison)
340 */
341 a.parts.sign = !a.parts.sign;
342 b.parts.sign = !b.parts.sign;
343 return lt128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
344}
345
346/**
347 * Greater-than comparison between two floats. NaNs are not recognized.
348 *
349 * @a First single-precision operand.
350 * @b Second single-precision operand.
351 * @return 1 if a is greater than b, 0 otherwise.
352 */
353int is_float32_gt(float32 a, float32 b)
354{
355 if (((a.bin | b.bin) & 0x7FFFFFFF) == 0) {
356 /* zeroes are equal with any sign */
357 return 0;
358 }
359
360 if ((a.parts.sign) && (b.parts.sign)) {
361 /* if both are negative, greater is that with smaller binary value */
362 return (a.bin < b.bin);
363 }
364
365 /*
366 * lets negate signs - now will be positive numbers always
367 * bigger than negative (first bit will be set for unsigned
368 * integer comparison)
369 */
370 a.parts.sign = !a.parts.sign;
371 b.parts.sign = !b.parts.sign;
372 return (a.bin > b.bin);
373}
374
375/**
376 * Greater-than comparison between two floats. NaNs are not recognized.
377 *
378 * @a First double-precision operand.
379 * @b Second double-precision operand.
380 * @return 1 if a is greater than b, 0 otherwise.
381 */
382int is_float64_gt(float64 a, float64 b)
383{
384 if (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0) {
385 /* zeroes are equal with any sign */
386 return 0;
387 }
388
389 if ((a.parts.sign) && (b.parts.sign)) {
390 /* if both are negative, greater is that with smaller binary value */
391 return (a.bin < b.bin);
392 }
393
394 /*
395 * lets negate signs - now will be positive numbers always
396 * bigger than negative (first bit will be set for unsigned
397 * integer comparison)
398 */
399 a.parts.sign = !a.parts.sign;
400 b.parts.sign = !b.parts.sign;
401 return (a.bin > b.bin);
402}
403
404/**
405 * Greater-than comparison between two floats. NaNs are not recognized.
406 *
407 * @a First quadruple-precision operand.
408 * @b Second quadruple-precision operand.
409 * @return 1 if a is greater than b, 0 otherwise.
410 */
411int is_float128_gt(float128 a, float128 b)
412{
413 uint64_t tmp_hi;
414 uint64_t tmp_lo;
415
416 or128(a.bin.hi, a.bin.lo,
417 b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
418 and128(tmp_hi, tmp_lo,
419 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
420 if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
421 /* zeroes are equal with any sign */
422 return 0;
423 }
424
425 if ((a.parts.sign) && (b.parts.sign)) {
426 /* if both are negative, greater is that with smaller binary value */
427 return lt128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
428 }
429
430 /*
431 * lets negate signs - now will be positive numbers always
432 * bigger than negative (first bit will be set for unsigned
433 * integer comparison)
434 */
435 a.parts.sign = !a.parts.sign;
436 b.parts.sign = !b.parts.sign;
437 return lt128(b.bin.hi, b.bin.lo, a.bin.hi, a.bin.lo);
438}
439
440#ifdef float32_t
441
442int __gtsf2(float32_t a, float32_t b)
443{
444 float32_u ua;
445 ua.val = a;
446
447 float32_u ub;
448 ub.val = b;
449
450 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
451 // TODO: sigNaNs
452 return -1;
453 }
454
455 if (is_float32_gt(ua.data, ub.data))
456 return 1;
457
458 return 0;
459}
460
461int __gesf2(float32_t a, float32_t b)
462{
463 float32_u ua;
464 ua.val = a;
465
466 float32_u ub;
467 ub.val = b;
468
469 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
470 // TODO: sigNaNs
471 return -1;
472 }
473
474 if (is_float32_eq(ua.data, ub.data))
475 return 0;
476
477 if (is_float32_gt(ua.data, ub.data))
478 return 1;
479
480 return -1;
481}
482
483int __ltsf2(float32_t a, float32_t b)
484{
485 float32_u ua;
486 ua.val = a;
487
488 float32_u ub;
489 ub.val = b;
490
491 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
492 // TODO: sigNaNs
493 return 1;
494 }
495
496 if (is_float32_lt(ua.data, ub.data))
497 return -1;
498
499 return 0;
500}
501
502int __lesf2(float32_t a, float32_t b)
503{
504 float32_u ua;
505 ua.val = a;
506
507 float32_u ub;
508 ub.val = b;
509
510 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
511 // TODO: sigNaNs
512 return 1;
513 }
514
515 if (is_float32_eq(ua.data, ub.data))
516 return 0;
517
518 if (is_float32_lt(ua.data, ub.data))
519 return -1;
520
521 return 1;
522}
523
524int __eqsf2(float32_t a, float32_t b)
525{
526 float32_u ua;
527 ua.val = a;
528
529 float32_u ub;
530 ub.val = b;
531
532 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
533 // TODO: sigNaNs
534 return 1;
535 }
536
537 return is_float32_eq(ua.data, ub.data) - 1;
538}
539
540int __nesf2(float32_t a, float32_t b)
541{
542 /* Strange, but according to GCC documentation */
543 return __eqsf2(a, b);
544}
545
546int __cmpsf2(float32_t a, float32_t b)
547{
548 float32_u ua;
549 ua.val = a;
550
551 float32_u ub;
552 ub.val = b;
553
554 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
555 /* No special constant for unordered - maybe signaled? */
556 return 1;
557 }
558
559 if (is_float32_eq(ua.data, ub.data))
560 return 0;
561
562 if (is_float32_lt(ua.data, ub.data))
563 return -1;
564
565 return 1;
566}
567
568int __unordsf2(float32_t a, float32_t b)
569{
570 float32_u ua;
571 ua.val = a;
572
573 float32_u ub;
574 ub.val = b;
575
576 return ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data)));
577}
578
579int __aeabi_fcmpgt(float32_t a, float32_t b)
580{
581 float32_u ua;
582 ua.val = a;
583
584 float32_u ub;
585 ub.val = b;
586
587 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
588 // TODO: sigNaNs
589 return 0;
590 }
591
592 if (is_float32_gt(ua.data, ub.data))
593 return 1;
594
595 return 0;
596}
597
598int __aeabi_fcmplt(float32_t a, float32_t b)
599{
600 float32_u ua;
601 ua.val = a;
602
603 float32_u ub;
604 ub.val = b;
605
606 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
607 // TODO: sigNaNs
608 return 0;
609 }
610
611 if (is_float32_lt(ua.data, ub.data))
612 return 1;
613
614 return 0;
615}
616
617int __aeabi_fcmpge(float32_t a, float32_t b)
618{
619 float32_u ua;
620 ua.val = a;
621
622 float32_u ub;
623 ub.val = b;
624
625 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
626 // TODO: sigNaNs
627 return 0;
628 }
629
630 if (is_float32_eq(ua.data, ub.data))
631 return 1;
632
633 if (is_float32_gt(ua.data, ub.data))
634 return 1;
635
636 return 0;
637}
638
639int __aeabi_fcmple(float32_t a, float32_t b)
640{
641 float32_u ua;
642 ua.val = a;
643
644 float32_u ub;
645 ub.val = b;
646
647 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
648 // TODO: sigNaNs
649 return 0;
650 }
651
652 if (is_float32_eq(ua.data, ub.data))
653 return 1;
654
655 if (is_float32_lt(ua.data, ub.data))
656 return 1;
657
658 return 0;
659}
660
661int __aeabi_fcmpeq(float32_t a, float32_t b)
662{
663 float32_u ua;
664 ua.val = a;
665
666 float32_u ub;
667 ub.val = b;
668
669 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
670 // TODO: sigNaNs
671 return 0;
672 }
673
674 return is_float32_eq(ua.data, ub.data);
675}
676
677#endif
678
679#ifdef float64_t
680
681int __gtdf2(float64_t a, float64_t b)
682{
683 float64_u ua;
684 ua.val = a;
685
686 float64_u ub;
687 ub.val = b;
688
689 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
690 // TODO: sigNaNs
691 return -1;
692 }
693
694 if (is_float64_gt(ua.data, ub.data))
695 return 1;
696
697 return 0;
698}
699
700int __gedf2(float64_t a, float64_t b)
701{
702 float64_u ua;
703 ua.val = a;
704
705 float64_u ub;
706 ub.val = b;
707
708 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
709 // TODO: sigNaNs
710 return -1;
711 }
712
713 if (is_float64_eq(ua.data, ub.data))
714 return 0;
715
716 if (is_float64_gt(ua.data, ub.data))
717 return 1;
718
719 return -1;
720}
721
722int __ltdf2(float64_t a, float64_t b)
723{
724 float64_u ua;
725 ua.val = a;
726
727 float64_u ub;
728 ub.val = b;
729
730 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
731 // TODO: sigNaNs
732 return 1;
733 }
734
735 if (is_float64_lt(ua.data, ub.data))
736 return -1;
737
738 return 0;
739}
740
741int __ledf2(float64_t a, float64_t b)
742{
743 float64_u ua;
744 ua.val = a;
745
746 float64_u ub;
747 ub.val = b;
748
749 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
750 // TODO: sigNaNs
751 return 1;
752 }
753
754 if (is_float64_eq(ua.data, ub.data))
755 return 0;
756
757 if (is_float64_lt(ua.data, ub.data))
758 return -1;
759
760 return 1;
761}
762
763int __eqdf2(float64_t a, float64_t b)
764{
765 float64_u ua;
766 ua.val = a;
767
768 float64_u ub;
769 ub.val = b;
770
771 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
772 // TODO: sigNaNs
773 return 1;
774 }
775
776 return is_float64_eq(ua.data, ub.data) - 1;
777}
778
779int __nedf2(float64_t a, float64_t b)
780{
781 /* Strange, but according to GCC documentation */
782 return __eqdf2(a, b);
783}
784
785int __cmpdf2(float64_t a, float64_t b)
786{
787 float64_u ua;
788 ua.val = a;
789
790 float64_u ub;
791 ub.val = b;
792
793 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
794 /* No special constant for unordered - maybe signaled? */
795 return 1;
796 }
797
798 if (is_float64_eq(ua.data, ub.data))
799 return 0;
800
801 if (is_float64_lt(ua.data, ub.data))
802 return -1;
803
804 return 1;
805}
806
807int __unorddf2(float64_t a, float64_t b)
808{
809 float64_u ua;
810 ua.val = a;
811
812 float64_u ub;
813 ub.val = b;
814
815 return ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data)));
816}
817
818int __aeabi_dcmplt(float64_t a, float64_t b)
819{
820 float64_u ua;
821 ua.val = a;
822
823 float64_u ub;
824 ub.val = b;
825
826 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
827 // TODO: sigNaNs
828 return 0;
829 }
830
831 if (is_float64_lt(ua.data, ub.data))
832 return 1;
833
834 return 0;
835}
836
837int __aeabi_dcmpeq(float64_t a, float64_t b)
838{
839 float64_u ua;
840 ua.val = a;
841
842 float64_u ub;
843 ub.val = b;
844
845 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
846 // TODO: sigNaNs
847 return 0;
848 }
849
850 return is_float64_eq(ua.data, ub.data);
851}
852
853int __aeabi_dcmpgt(float64_t a, float64_t b)
854{
855 float64_u ua;
856 ua.val = a;
857
858 float64_u ub;
859 ub.val = b;
860
861 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
862 // TODO: sigNaNs
863 return 0;
864 }
865
866 if (is_float64_gt(ua.data, ub.data))
867 return 1;
868
869 return 0;
870}
871
872int __aeabi_dcmpge(float64_t a, float64_t b)
873{
874 float64_u ua;
875 ua.val = a;
876
877 float64_u ub;
878 ub.val = b;
879
880 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
881 // TODO: sigNaNs
882 return 0;
883 }
884
885 if (is_float64_eq(ua.data, ub.data))
886 return 1;
887
888 if (is_float64_gt(ua.data, ub.data))
889 return 1;
890
891 return 0;
892}
893
894int __aeabi_dcmple(float64_t a, float64_t b)
895{
896 float64_u ua;
897 ua.val = a;
898
899 float64_u ub;
900 ub.val = b;
901
902 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
903 // TODO: sigNaNs
904 return 0;
905 }
906
907 if (is_float64_eq(ua.data, ub.data))
908 return 1;
909
910 if (is_float64_lt(ua.data, ub.data))
911 return 1;
912
913 return 0;
914}
915
916#endif
917
918#ifdef float128_t
919
920int __gttf2(float128_t a, float128_t b)
921{
922 float128_u ua;
923 ua.val = a;
924
925 float128_u ub;
926 ub.val = b;
927
928 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
929 // TODO: sigNaNs
930 return -1;
931 }
932
933 if (is_float128_gt(ua.data, ub.data))
934 return 1;
935
936 return 0;
937}
938
939int __getf2(float128_t a, float128_t b)
940{
941 float128_u ua;
942 ua.val = a;
943
944 float128_u ub;
945 ub.val = b;
946
947 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
948 // TODO: sigNaNs
949 return -1;
950 }
951
952 if (is_float128_eq(ua.data, ub.data))
953 return 0;
954
955 if (is_float128_gt(ua.data, ub.data))
956 return 1;
957
958 return -1;
959}
960
961int __lttf2(float128_t a, float128_t b)
962{
963 float128_u ua;
964 ua.val = a;
965
966 float128_u ub;
967 ub.val = b;
968
969 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
970 // TODO: sigNaNs
971 return 1;
972 }
973
974 if (is_float128_lt(ua.data, ub.data))
975 return -1;
976
977 return 0;
978}
979
980int __letf2(float128_t a, float128_t b)
981{
982 float128_u ua;
983 ua.val = a;
984
985 float128_u ub;
986 ub.val = b;
987
988 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
989 // TODO: sigNaNs
990 return 1;
991 }
992
993 if (is_float128_eq(ua.data, ub.data))
994 return 0;
995
996 if (is_float128_lt(ua.data, ub.data))
997 return -1;
998
999 return 1;
1000}
1001
1002int __eqtf2(float128_t a, float128_t b)
1003{
1004 float128_u ua;
1005 ua.val = a;
1006
1007 float128_u ub;
1008 ub.val = b;
1009
1010 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
1011 // TODO: sigNaNs
1012 return 1;
1013 }
1014
1015 return is_float128_eq(ua.data, ub.data) - 1;
1016}
1017
1018int __netf2(float128_t a, float128_t b)
1019{
1020 /* Strange, but according to GCC documentation */
1021 return __eqtf2(a, b);
1022}
1023
1024int __cmptf2(float128_t a, float128_t b)
1025{
1026 float128_u ua;
1027 ua.val = a;
1028
1029 float128_u ub;
1030 ub.val = b;
1031
1032 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
1033 /* No special constant for unordered - maybe signaled? */
1034 return 1;
1035 }
1036
1037 if (is_float128_eq(ua.data, ub.data))
1038 return 0;
1039
1040 if (is_float128_lt(ua.data, ub.data))
1041 return -1;
1042
1043 return 1;
1044}
1045
1046int __unordtf2(float128_t a, float128_t b)
1047{
1048 float128_u ua;
1049 ua.val = a;
1050
1051 float128_u ub;
1052 ub.val = b;
1053
1054 return ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)));
1055}
1056
1057int _Qp_cmp(float128_t *a, float128_t *b)
1058{
1059 float128_u ua;
1060 ua.val = *a;
1061
1062 float128_u ub;
1063 ub.val = *b;
1064
1065 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1066 return 3;
1067
1068 if (is_float128_eq(ua.data, ub.data))
1069 return 0;
1070
1071 if (is_float128_lt(ua.data, ub.data))
1072 return 1;
1073
1074 return 2;
1075}
1076
1077int _Qp_cmpe(float128_t *a, float128_t *b)
1078{
1079 /* Strange, but according to SPARC Compliance Definition */
1080 return _Qp_cmp(a, b);
1081}
1082
1083int _Qp_fgt(float128_t *a, float128_t *b)
1084{
1085 float128_u ua;
1086 ua.val = *a;
1087
1088 float128_u ub;
1089 ub.val = *b;
1090
1091 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1092 return 0;
1093
1094 return is_float128_gt(ua.data, ub.data);
1095}
1096
1097int _Qp_fge(float128_t *a, float128_t *b)
1098{
1099 float128_u ua;
1100 ua.val = *a;
1101
1102 float128_u ub;
1103 ub.val = *b;
1104
1105 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1106 return 0;
1107
1108 return is_float128_eq(ua.data, ub.data) ||
1109 is_float128_gt(ua.data, ub.data);
1110}
1111
1112int _Qp_flt(float128_t *a, float128_t *b)
1113{
1114 float128_u ua;
1115 ua.val = *a;
1116
1117 float128_u ub;
1118 ub.val = *b;
1119
1120 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1121 return 0;
1122
1123 return is_float128_lt(ua.data, ub.data);
1124}
1125
1126int _Qp_fle(float128_t *a, float128_t *b)
1127{
1128 float128_u ua;
1129 ua.val = *a;
1130
1131 float128_u ub;
1132 ub.val = *b;
1133
1134 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1135 return 0;
1136
1137 return is_float128_eq(ua.data, ub.data) ||
1138 is_float128_lt(ua.data, ub.data);
1139}
1140
1141int _Qp_feq(float128_t *a, float128_t *b)
1142{
1143 float128_u ua;
1144 ua.val = *a;
1145
1146 float128_u ub;
1147 ub.val = *b;
1148
1149 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1150 return 0;
1151
1152 return is_float128_eq(ua.data, ub.data);
1153}
1154
1155int _Qp_fne(float128_t *a, float128_t *b)
1156{
1157 float128_u ua;
1158 ua.val = *a;
1159
1160 float128_u ub;
1161 ub.val = *b;
1162
1163 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1164 return 0;
1165
1166 return !is_float128_eq(ua.data, ub.data);
1167}
1168
1169#endif
1170
1171/** @}
1172 */
Note: See TracBrowser for help on using the repository browser.