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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c300bb5 was 7c3fb9b, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix block comment formatting (ccheck).

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