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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since fa86fff was 516e780, checked in by GitHub <noreply@…>, 7 years ago

Strip down libmath. (#45)

libmath is mostly unused (except for trunc(), sin() and cos()), and most functions in it are either very imprecise or downright broken. Additionally, it is implemented in manner that conflicts with C standard. Instead of trying to fix all the shortcomings while maintaining unused functionality, I'm opting to simply remove most of it and only keep the parts that are currently necessary.

Later readdition of the removed functions is possible, but there needs to be a reliable way to evaluate their quality first.

  • 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.