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

Last change on this file since bbdca54 was ed9043f7, checked in by Jiří Zárevúcky <jiri.zarevucky@…>, 7 years ago

Add aeabi_fcmpun() and aeabi_dcmpun()

  • Property mode set to 100644
File size: 23.0 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
683int __aeabi_fcmpun(float32_t a, float32_t b)
684{
685 float32_u ua;
686 ua.val = a;
687
688 float32_u ub;
689 ub.val = b;
690
691 // TODO: sigNaNs
692 return is_float32_nan(ua.data) || is_float32_nan(ub.data);
693}
694
695#endif
696
697#ifdef float64_t
698
699int __gtdf2(float64_t a, float64_t b)
700{
701 float64_u ua;
702 ua.val = a;
703
704 float64_u ub;
705 ub.val = b;
706
707 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
708 // TODO: sigNaNs
709 return -1;
710 }
711
712 if (is_float64_gt(ua.data, ub.data))
713 return 1;
714
715 return 0;
716}
717
718int __gedf2(float64_t a, float64_t b)
719{
720 float64_u ua;
721 ua.val = a;
722
723 float64_u ub;
724 ub.val = b;
725
726 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
727 // TODO: sigNaNs
728 return -1;
729 }
730
731 if (is_float64_eq(ua.data, ub.data))
732 return 0;
733
734 if (is_float64_gt(ua.data, ub.data))
735 return 1;
736
737 return -1;
738}
739
740int __ltdf2(float64_t a, float64_t b)
741{
742 float64_u ua;
743 ua.val = a;
744
745 float64_u ub;
746 ub.val = b;
747
748 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
749 // TODO: sigNaNs
750 return 1;
751 }
752
753 if (is_float64_lt(ua.data, ub.data))
754 return -1;
755
756 return 0;
757}
758
759int __ledf2(float64_t a, float64_t b)
760{
761 float64_u ua;
762 ua.val = a;
763
764 float64_u ub;
765 ub.val = b;
766
767 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
768 // TODO: sigNaNs
769 return 1;
770 }
771
772 if (is_float64_eq(ua.data, ub.data))
773 return 0;
774
775 if (is_float64_lt(ua.data, ub.data))
776 return -1;
777
778 return 1;
779}
780
781int __eqdf2(float64_t a, float64_t b)
782{
783 float64_u ua;
784 ua.val = a;
785
786 float64_u ub;
787 ub.val = b;
788
789 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
790 // TODO: sigNaNs
791 return 1;
792 }
793
794 return is_float64_eq(ua.data, ub.data) - 1;
795}
796
797int __nedf2(float64_t a, float64_t b)
798{
799 /* Strange, but according to GCC documentation */
800 return __eqdf2(a, b);
801}
802
803int __cmpdf2(float64_t a, float64_t b)
804{
805 float64_u ua;
806 ua.val = a;
807
808 float64_u ub;
809 ub.val = b;
810
811 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
812 /* No special constant for unordered - maybe signaled? */
813 return 1;
814 }
815
816 if (is_float64_eq(ua.data, ub.data))
817 return 0;
818
819 if (is_float64_lt(ua.data, ub.data))
820 return -1;
821
822 return 1;
823}
824
825int __unorddf2(float64_t a, float64_t b)
826{
827 float64_u ua;
828 ua.val = a;
829
830 float64_u ub;
831 ub.val = b;
832
833 return ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data)));
834}
835
836int __aeabi_dcmplt(float64_t a, float64_t b)
837{
838 float64_u ua;
839 ua.val = a;
840
841 float64_u ub;
842 ub.val = b;
843
844 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
845 // TODO: sigNaNs
846 return 0;
847 }
848
849 if (is_float64_lt(ua.data, ub.data))
850 return 1;
851
852 return 0;
853}
854
855int __aeabi_dcmpeq(float64_t a, float64_t b)
856{
857 float64_u ua;
858 ua.val = a;
859
860 float64_u ub;
861 ub.val = b;
862
863 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
864 // TODO: sigNaNs
865 return 0;
866 }
867
868 return is_float64_eq(ua.data, ub.data);
869}
870
871int __aeabi_dcmpgt(float64_t a, float64_t b)
872{
873 float64_u ua;
874 ua.val = a;
875
876 float64_u ub;
877 ub.val = b;
878
879 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
880 // TODO: sigNaNs
881 return 0;
882 }
883
884 if (is_float64_gt(ua.data, ub.data))
885 return 1;
886
887 return 0;
888}
889
890int __aeabi_dcmpge(float64_t a, float64_t b)
891{
892 float64_u ua;
893 ua.val = a;
894
895 float64_u ub;
896 ub.val = b;
897
898 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
899 // TODO: sigNaNs
900 return 0;
901 }
902
903 if (is_float64_eq(ua.data, ub.data))
904 return 1;
905
906 if (is_float64_gt(ua.data, ub.data))
907 return 1;
908
909 return 0;
910}
911
912int __aeabi_dcmple(float64_t a, float64_t b)
913{
914 float64_u ua;
915 ua.val = a;
916
917 float64_u ub;
918 ub.val = b;
919
920 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
921 // TODO: sigNaNs
922 return 0;
923 }
924
925 if (is_float64_eq(ua.data, ub.data))
926 return 1;
927
928 if (is_float64_lt(ua.data, ub.data))
929 return 1;
930
931 return 0;
932}
933
934int __aeabi_dcmpun(float64_t a, float64_t b)
935{
936 float64_u ua;
937 ua.val = a;
938
939 float64_u ub;
940 ub.val = b;
941
942 // TODO: sigNaNs
943 return is_float64_nan(ua.data) || is_float64_nan(ub.data);
944}
945
946#endif
947
948#ifdef float128_t
949
950int __gttf2(float128_t a, float128_t b)
951{
952 float128_u ua;
953 ua.val = a;
954
955 float128_u ub;
956 ub.val = b;
957
958 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
959 // TODO: sigNaNs
960 return -1;
961 }
962
963 if (is_float128_gt(ua.data, ub.data))
964 return 1;
965
966 return 0;
967}
968
969int __getf2(float128_t a, float128_t b)
970{
971 float128_u ua;
972 ua.val = a;
973
974 float128_u ub;
975 ub.val = b;
976
977 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
978 // TODO: sigNaNs
979 return -1;
980 }
981
982 if (is_float128_eq(ua.data, ub.data))
983 return 0;
984
985 if (is_float128_gt(ua.data, ub.data))
986 return 1;
987
988 return -1;
989}
990
991int __lttf2(float128_t a, float128_t b)
992{
993 float128_u ua;
994 ua.val = a;
995
996 float128_u ub;
997 ub.val = b;
998
999 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
1000 // TODO: sigNaNs
1001 return 1;
1002 }
1003
1004 if (is_float128_lt(ua.data, ub.data))
1005 return -1;
1006
1007 return 0;
1008}
1009
1010int __letf2(float128_t a, float128_t b)
1011{
1012 float128_u ua;
1013 ua.val = a;
1014
1015 float128_u ub;
1016 ub.val = b;
1017
1018 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
1019 // TODO: sigNaNs
1020 return 1;
1021 }
1022
1023 if (is_float128_eq(ua.data, ub.data))
1024 return 0;
1025
1026 if (is_float128_lt(ua.data, ub.data))
1027 return -1;
1028
1029 return 1;
1030}
1031
1032int __eqtf2(float128_t a, float128_t b)
1033{
1034 float128_u ua;
1035 ua.val = a;
1036
1037 float128_u ub;
1038 ub.val = b;
1039
1040 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
1041 // TODO: sigNaNs
1042 return 1;
1043 }
1044
1045 return is_float128_eq(ua.data, ub.data) - 1;
1046}
1047
1048int __netf2(float128_t a, float128_t b)
1049{
1050 /* Strange, but according to GCC documentation */
1051 return __eqtf2(a, b);
1052}
1053
1054int __cmptf2(float128_t a, float128_t b)
1055{
1056 float128_u ua;
1057 ua.val = a;
1058
1059 float128_u ub;
1060 ub.val = b;
1061
1062 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
1063 /* No special constant for unordered - maybe signaled? */
1064 return 1;
1065 }
1066
1067 if (is_float128_eq(ua.data, ub.data))
1068 return 0;
1069
1070 if (is_float128_lt(ua.data, ub.data))
1071 return -1;
1072
1073 return 1;
1074}
1075
1076int __unordtf2(float128_t a, float128_t b)
1077{
1078 float128_u ua;
1079 ua.val = a;
1080
1081 float128_u ub;
1082 ub.val = b;
1083
1084 return ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)));
1085}
1086
1087int _Qp_cmp(float128_t *a, float128_t *b)
1088{
1089 float128_u ua;
1090 ua.val = *a;
1091
1092 float128_u ub;
1093 ub.val = *b;
1094
1095 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1096 return 3;
1097
1098 if (is_float128_eq(ua.data, ub.data))
1099 return 0;
1100
1101 if (is_float128_lt(ua.data, ub.data))
1102 return 1;
1103
1104 return 2;
1105}
1106
1107int _Qp_cmpe(float128_t *a, float128_t *b)
1108{
1109 /* Strange, but according to SPARC Compliance Definition */
1110 return _Qp_cmp(a, b);
1111}
1112
1113int _Qp_fgt(float128_t *a, float128_t *b)
1114{
1115 float128_u ua;
1116 ua.val = *a;
1117
1118 float128_u ub;
1119 ub.val = *b;
1120
1121 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1122 return 0;
1123
1124 return is_float128_gt(ua.data, ub.data);
1125}
1126
1127int _Qp_fge(float128_t *a, float128_t *b)
1128{
1129 float128_u ua;
1130 ua.val = *a;
1131
1132 float128_u ub;
1133 ub.val = *b;
1134
1135 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1136 return 0;
1137
1138 return is_float128_eq(ua.data, ub.data) ||
1139 is_float128_gt(ua.data, ub.data);
1140}
1141
1142int _Qp_flt(float128_t *a, float128_t *b)
1143{
1144 float128_u ua;
1145 ua.val = *a;
1146
1147 float128_u ub;
1148 ub.val = *b;
1149
1150 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1151 return 0;
1152
1153 return is_float128_lt(ua.data, ub.data);
1154}
1155
1156int _Qp_fle(float128_t *a, float128_t *b)
1157{
1158 float128_u ua;
1159 ua.val = *a;
1160
1161 float128_u ub;
1162 ub.val = *b;
1163
1164 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1165 return 0;
1166
1167 return is_float128_eq(ua.data, ub.data) ||
1168 is_float128_lt(ua.data, ub.data);
1169}
1170
1171int _Qp_feq(float128_t *a, float128_t *b)
1172{
1173 float128_u ua;
1174 ua.val = *a;
1175
1176 float128_u ub;
1177 ub.val = *b;
1178
1179 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1180 return 0;
1181
1182 return is_float128_eq(ua.data, ub.data);
1183}
1184
1185int _Qp_fne(float128_t *a, float128_t *b)
1186{
1187 float128_u ua;
1188 ua.val = *a;
1189
1190 float128_u ub;
1191 ub.val = *b;
1192
1193 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1194 return 0;
1195
1196 return !is_float128_eq(ua.data, ub.data);
1197}
1198
1199#endif
1200
1201/** @}
1202 */
Note: See TracBrowser for help on using the repository browser.