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

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

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 22.3 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.