source: mainline/uspace/lib/softfloat/comparison.c@ 3061bc1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3061bc1 was 1b20da0, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on non-empty lines, in certain file types.

Command used: tools/srepl '\([^[:space:]]\)\s\+$' '\1' -- *.c *.h *.py *.sh *.s *.S *.ag

  • Property mode set to 100644
File size: 22.4 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 -1;
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 1;
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 -1;
628 }
629
630 if (is_float32_eq(ua.data, ub.data))
631 return 0;
632
633 if (is_float32_gt(ua.data, ub.data))
634 return 1;
635
636 return -1;
637}
638
639int __aeabi_fcmpeq(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 1;
650 }
651
652 return is_float32_eq(ua.data, ub.data) - 1;
653}
654
655#endif
656
657#ifdef float64_t
658
659int __gtdf2(float64_t a, float64_t b)
660{
661 float64_u ua;
662 ua.val = a;
663
664 float64_u ub;
665 ub.val = b;
666
667 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
668 // TODO: sigNaNs
669 return -1;
670 }
671
672 if (is_float64_gt(ua.data, ub.data))
673 return 1;
674
675 return 0;
676}
677
678int __gedf2(float64_t a, float64_t b)
679{
680 float64_u ua;
681 ua.val = a;
682
683 float64_u ub;
684 ub.val = b;
685
686 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
687 // TODO: sigNaNs
688 return -1;
689 }
690
691 if (is_float64_eq(ua.data, ub.data))
692 return 0;
693
694 if (is_float64_gt(ua.data, ub.data))
695 return 1;
696
697 return -1;
698}
699
700int __ltdf2(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_lt(ua.data, ub.data))
714 return -1;
715
716 return 0;
717}
718
719int __ledf2(float64_t a, float64_t b)
720{
721 float64_u ua;
722 ua.val = a;
723
724 float64_u ub;
725 ub.val = b;
726
727 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
728 // TODO: sigNaNs
729 return 1;
730 }
731
732 if (is_float64_eq(ua.data, ub.data))
733 return 0;
734
735 if (is_float64_lt(ua.data, ub.data))
736 return -1;
737
738 return 1;
739}
740
741int __eqdf2(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 return is_float64_eq(ua.data, ub.data) - 1;
755}
756
757int __nedf2(float64_t a, float64_t b)
758{
759 /* Strange, but according to GCC documentation */
760 return __eqdf2(a, b);
761}
762
763int __cmpdf2(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 /* No special constant for unordered - maybe signaled? */
773 return 1;
774 }
775
776 if (is_float64_eq(ua.data, ub.data))
777 return 0;
778
779 if (is_float64_lt(ua.data, ub.data))
780 return -1;
781
782 return 1;
783}
784
785int __unorddf2(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 return ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data)));
794}
795
796int __aeabi_dcmplt(float64_t a, float64_t b)
797{
798 float64_u ua;
799 ua.val = a;
800
801 float64_u ub;
802 ub.val = b;
803
804 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
805 // TODO: sigNaNs
806 return 1;
807 }
808
809 if (is_float64_lt(ua.data, ub.data))
810 return -1;
811
812 return 0;
813}
814
815int __aeabi_dcmpeq(float64_t a, float64_t b)
816{
817 float64_u ua;
818 ua.val = a;
819
820 float64_u ub;
821 ub.val = b;
822
823 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
824 // TODO: sigNaNs
825 return 1;
826 }
827
828 return is_float64_eq(ua.data, ub.data) - 1;
829}
830
831int __aeabi_dcmpgt(float64_t a, float64_t b)
832{
833 float64_u ua;
834 ua.val = a;
835
836 float64_u ub;
837 ub.val = b;
838
839 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
840 // TODO: sigNaNs
841 return -1;
842 }
843
844 if (is_float64_gt(ua.data, ub.data))
845 return 1;
846
847 return 0;
848}
849
850int __aeabi_dcmpge(float64_t a, float64_t b)
851{
852 float64_u ua;
853 ua.val = a;
854
855 float64_u ub;
856 ub.val = b;
857
858 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
859 // TODO: sigNaNs
860 return -1;
861 }
862
863 if (is_float64_eq(ua.data, ub.data))
864 return 0;
865
866 if (is_float64_gt(ua.data, ub.data))
867 return 1;
868
869 return -1;
870}
871
872int __aeabi_dcmple(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 1;
883 }
884
885 if (is_float64_eq(ua.data, ub.data))
886 return 0;
887
888 if (is_float64_lt(ua.data, ub.data))
889 return -1;
890
891 return 1;
892}
893
894#endif
895
896#ifdef float128_t
897
898int __gttf2(float128_t a, float128_t b)
899{
900 float128_u ua;
901 ua.val = a;
902
903 float128_u ub;
904 ub.val = b;
905
906 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
907 // TODO: sigNaNs
908 return -1;
909 }
910
911 if (is_float128_gt(ua.data, ub.data))
912 return 1;
913
914 return 0;
915}
916
917int __getf2(float128_t a, float128_t b)
918{
919 float128_u ua;
920 ua.val = a;
921
922 float128_u ub;
923 ub.val = b;
924
925 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
926 // TODO: sigNaNs
927 return -1;
928 }
929
930 if (is_float128_eq(ua.data, ub.data))
931 return 0;
932
933 if (is_float128_gt(ua.data, ub.data))
934 return 1;
935
936 return -1;
937}
938
939int __lttf2(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_lt(ua.data, ub.data))
953 return -1;
954
955 return 0;
956}
957
958int __letf2(float128_t a, float128_t b)
959{
960 float128_u ua;
961 ua.val = a;
962
963 float128_u ub;
964 ub.val = b;
965
966 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
967 // TODO: sigNaNs
968 return 1;
969 }
970
971 if (is_float128_eq(ua.data, ub.data))
972 return 0;
973
974 if (is_float128_lt(ua.data, ub.data))
975 return -1;
976
977 return 1;
978}
979
980int __eqtf2(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 return is_float128_eq(ua.data, ub.data) - 1;
994}
995
996int __netf2(float128_t a, float128_t b)
997{
998 /* Strange, but according to GCC documentation */
999 return __eqtf2(a, b);
1000}
1001
1002int __cmptf2(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 /* No special constant for unordered - maybe signaled? */
1012 return 1;
1013 }
1014
1015 if (is_float128_eq(ua.data, ub.data))
1016 return 0;
1017
1018 if (is_float128_lt(ua.data, ub.data))
1019 return -1;
1020
1021 return 1;
1022}
1023
1024int __unordtf2(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 return ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)));
1033}
1034
1035int _Qp_cmp(float128_t *a, float128_t *b)
1036{
1037 float128_u ua;
1038 ua.val = *a;
1039
1040 float128_u ub;
1041 ub.val = *b;
1042
1043 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1044 return 3;
1045
1046 if (is_float128_eq(ua.data, ub.data))
1047 return 0;
1048
1049 if (is_float128_lt(ua.data, ub.data))
1050 return 1;
1051
1052 return 2;
1053}
1054
1055int _Qp_cmpe(float128_t *a, float128_t *b)
1056{
1057 /* Strange, but according to SPARC Compliance Definition */
1058 return _Qp_cmp(a, b);
1059}
1060
1061int _Qp_fgt(float128_t *a, float128_t *b)
1062{
1063 float128_u ua;
1064 ua.val = *a;
1065
1066 float128_u ub;
1067 ub.val = *b;
1068
1069 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1070 return 0;
1071
1072 return is_float128_gt(ua.data, ub.data);
1073}
1074
1075int _Qp_fge(float128_t *a, float128_t *b)
1076{
1077 float128_u ua;
1078 ua.val = *a;
1079
1080 float128_u ub;
1081 ub.val = *b;
1082
1083 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1084 return 0;
1085
1086 return is_float128_eq(ua.data, ub.data) ||
1087 is_float128_gt(ua.data, ub.data);
1088}
1089
1090int _Qp_flt(float128_t *a, float128_t *b)
1091{
1092 float128_u ua;
1093 ua.val = *a;
1094
1095 float128_u ub;
1096 ub.val = *b;
1097
1098 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1099 return 0;
1100
1101 return is_float128_lt(ua.data, ub.data);
1102}
1103
1104int _Qp_fle(float128_t *a, float128_t *b)
1105{
1106 float128_u ua;
1107 ua.val = *a;
1108
1109 float128_u ub;
1110 ub.val = *b;
1111
1112 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1113 return 0;
1114
1115 return is_float128_eq(ua.data, ub.data) ||
1116 is_float128_lt(ua.data, ub.data);
1117}
1118
1119int _Qp_feq(float128_t *a, float128_t *b)
1120{
1121 float128_u ua;
1122 ua.val = *a;
1123
1124 float128_u ub;
1125 ub.val = *b;
1126
1127 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1128 return 0;
1129
1130 return is_float128_eq(ua.data, ub.data);
1131}
1132
1133int _Qp_fne(float128_t *a, float128_t *b)
1134{
1135 float128_u ua;
1136 ua.val = *a;
1137
1138 float128_u ub;
1139 ub.val = *b;
1140
1141 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1142 return 0;
1143
1144 return !is_float128_eq(ua.data, ub.data);
1145}
1146
1147#endif
1148
1149/** @}
1150 */
Note: See TracBrowser for help on using the repository browser.