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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a0a273e was c0c38c7c, checked in by Martin Decky <martin@…>, 10 years ago

software floating point overhaul
use proper type mapping
fix cosine calculation

  • Property mode set to 100644
File size: 22.4 KB
RevLine 
[b5440cf]1/*
[df4ed85]2 * Copyright (c) 2005 Josef Cejka
[c67aff2]3 * Copyright (c) 2011 Petr Koupy
[b5440cf]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
[750636a]30/** @addtogroup softfloat
[846848a6]31 * @{
32 */
[c67aff2]33/** @file Comparison functions.
[846848a6]34 */
35
[2416085]36#include "comparison.h"
37#include "common.h"
[b5440cf]38
[c67aff2]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 */
[88d5c1e]46int is_float32_nan(float32 f)
[750636a]47{
[c67aff2]48 /* NaN : exp = 0xff and nonzero fraction */
[750636a]49 return ((f.parts.exp == 0xFF) && (f.parts.fraction));
[e591928]50}
[b5440cf]51
[c67aff2]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 */
[88d5c1e]59int is_float64_nan(float64 d)
[750636a]60{
[c67aff2]61 /* NaN : exp = 0x7ff and nonzero fraction */
[750636a]62 return ((d.parts.exp == 0x7FF) && (d.parts.fraction));
[e591928]63}
[feef1cd]64
[c67aff2]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 */
[88d5c1e]72int is_float128_nan(float128 ld)
[c67aff2]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 */
[88d5c1e]85int is_float32_signan(float32 f)
[750636a]86{
[c67aff2]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));
[e591928]91}
[b5440cf]92
[c67aff2]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 */
[88d5c1e]99int is_float64_signan(float64 d)
[750636a]100{
[c67aff2]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));
[e591928]105}
[feef1cd]106
[c67aff2]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 */
[88d5c1e]113int is_float128_signan(float128 ld)
[c67aff2]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 */
[88d5c1e]129int is_float32_infinity(float32 f)
[7e557805]130{
[c67aff2]131 /* NaN : exp = 0x7ff and zero fraction */
[750636a]132 return ((f.parts.exp == 0xFF) && (f.parts.fraction == 0x0));
[e591928]133}
[7e557805]134
[c67aff2]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 */
[88d5c1e]141int is_float64_infinity(float64 d)
[feef1cd]142{
[c67aff2]143 /* NaN : exp = 0x7ff and zero fraction */
[750636a]144 return ((d.parts.exp == 0x7FF) && (d.parts.fraction == 0x0));
[e591928]145}
[feef1cd]146
[c67aff2]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 */
[88d5c1e]153int is_float128_infinity(float128 ld)
[c67aff2]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 */
[88d5c1e]166int is_float32_zero(float32 f)
[3af72dc]167{
[88d5c1e]168 return (((f.bin) & 0x7FFFFFFF) == 0);
[3af72dc]169}
170
[c67aff2]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 */
[88d5c1e]177int is_float64_zero(float64 d)
[feef1cd]178{
[88d5c1e]179 return (((d.bin) & 0x7FFFFFFFFFFFFFFFll) == 0);
[feef1cd]180}
181
[7e557805]182/**
[c67aff2]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 */
[88d5c1e]188int is_float128_zero(float128 ld)
[c67aff2]189{
190 uint64_t tmp_hi;
191 uint64_t tmp_lo;
[88d5c1e]192
193 and128(ld.bin.hi, ld.bin.lo,
[c67aff2]194 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
[88d5c1e]195
[c67aff2]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.
[7e557805]205 */
[88d5c1e]206int is_float32_eq(float32 a, float32 b)
[7e557805]207{
[750636a]208 /* a equals to b or both are zeros (with any sign) */
[88d5c1e]209 return ((a.bin == b.bin) ||
210 (((a.bin | b.bin) & 0x7FFFFFFF) == 0));
[c67aff2]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 */
[88d5c1e]220int is_float64_eq(float64 a, float64 b)
[c67aff2]221{
222 /* a equals to b or both are zeros (with any sign) */
[88d5c1e]223 return ((a.bin == b.bin) ||
224 (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0));
[c67aff2]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 */
[88d5c1e]234int is_float128_eq(float128 a, float128 b)
[c67aff2]235{
236 uint64_t tmp_hi;
237 uint64_t tmp_lo;
[88d5c1e]238
[c67aff2]239 /* both are zeros (with any sign) */
[88d5c1e]240 or128(a.bin.hi, a.bin.lo,
241 b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
[c67aff2]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 */
[88d5c1e]247 int are_equal = eq128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
248
[c67aff2]249 return are_equal || both_zero;
[7e557805]250}
251
252/**
[c67aff2]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.
[7e557805]258 */
[88d5c1e]259int is_float32_lt(float32 a, float32 b)
[7e557805]260{
[88d5c1e]261 if (((a.bin | b.bin) & 0x7FFFFFFF) == 0) {
262 /* +- zeroes */
263 return 0;
[c67aff2]264 }
[cf4a823]265
[c67aff2]266 if ((a.parts.sign) && (b.parts.sign)) {
[750636a]267 /* if both are negative, smaller is that with greater binary value */
[88d5c1e]268 return (a.bin > b.bin);
[c67aff2]269 }
[cf4a823]270
[88d5c1e]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 */
[750636a]276 a.parts.sign = !a.parts.sign;
277 b.parts.sign = !b.parts.sign;
[88d5c1e]278 return (a.bin < b.bin);
[7e557805]279}
280
[e649dfa]281/**
[c67aff2]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 */
[88d5c1e]288int is_float64_lt(float64 a, float64 b)
[c67aff2]289{
[88d5c1e]290 if (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0) {
291 /* +- zeroes */
292 return 0;
[c67aff2]293 }
[88d5c1e]294
[c67aff2]295 if ((a.parts.sign) && (b.parts.sign)) {
296 /* if both are negative, smaller is that with greater binary value */
[88d5c1e]297 return (a.bin > b.bin);
[c67aff2]298 }
[88d5c1e]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 */
[c67aff2]305 a.parts.sign = !a.parts.sign;
306 b.parts.sign = !b.parts.sign;
[88d5c1e]307 return (a.bin < b.bin);
[c67aff2]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 */
[88d5c1e]317int is_float128_lt(float128 a, float128 b)
[c67aff2]318{
319 uint64_t tmp_hi;
320 uint64_t tmp_lo;
[88d5c1e]321
322 or128(a.bin.hi, a.bin.lo,
323 b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
[c67aff2]324 and128(tmp_hi, tmp_lo,
325 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
326 if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
[88d5c1e]327 /* +- zeroes */
328 return 0;
[c67aff2]329 }
[88d5c1e]330
[c67aff2]331 if ((a.parts.sign) && (b.parts.sign)) {
332 /* if both are negative, smaller is that with greater binary value */
[88d5c1e]333 return lt128(b.bin.hi, b.bin.lo, a.bin.hi, a.bin.lo);
[c67aff2]334 }
[88d5c1e]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 */
[c67aff2]341 a.parts.sign = !a.parts.sign;
342 b.parts.sign = !b.parts.sign;
[88d5c1e]343 return lt128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
[c67aff2]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.
[e649dfa]352 */
[88d5c1e]353int is_float32_gt(float32 a, float32 b)
[e649dfa]354{
[88d5c1e]355 if (((a.bin | b.bin) & 0x7FFFFFFF) == 0) {
356 /* zeroes are equal with any sign */
357 return 0;
[c67aff2]358 }
[cf4a823]359
[c67aff2]360 if ((a.parts.sign) && (b.parts.sign)) {
[750636a]361 /* if both are negative, greater is that with smaller binary value */
[88d5c1e]362 return (a.bin < b.bin);
[c67aff2]363 }
[cf4a823]364
[88d5c1e]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 */
[750636a]370 a.parts.sign = !a.parts.sign;
371 b.parts.sign = !b.parts.sign;
[88d5c1e]372 return (a.bin > b.bin);
[e649dfa]373}
374
[c67aff2]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 */
[88d5c1e]382int is_float64_gt(float64 a, float64 b)
[c67aff2]383{
[88d5c1e]384 if (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0) {
385 /* zeroes are equal with any sign */
386 return 0;
[c67aff2]387 }
[88d5c1e]388
[c67aff2]389 if ((a.parts.sign) && (b.parts.sign)) {
390 /* if both are negative, greater is that with smaller binary value */
[88d5c1e]391 return (a.bin < b.bin);
[c67aff2]392 }
[88d5c1e]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 */
[c67aff2]399 a.parts.sign = !a.parts.sign;
400 b.parts.sign = !b.parts.sign;
[88d5c1e]401 return (a.bin > b.bin);
[c67aff2]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 */
[88d5c1e]411int is_float128_gt(float128 a, float128 b)
[c67aff2]412{
413 uint64_t tmp_hi;
414 uint64_t tmp_lo;
[88d5c1e]415
416 or128(a.bin.hi, a.bin.lo,
417 b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
[c67aff2]418 and128(tmp_hi, tmp_lo,
419 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
420 if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
[88d5c1e]421 /* zeroes are equal with any sign */
422 return 0;
[c67aff2]423 }
[88d5c1e]424
[c67aff2]425 if ((a.parts.sign) && (b.parts.sign)) {
426 /* if both are negative, greater is that with smaller binary value */
[88d5c1e]427 return lt128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
[c67aff2]428 }
[88d5c1e]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 */
[c67aff2]435 a.parts.sign = !a.parts.sign;
436 b.parts.sign = !b.parts.sign;
[88d5c1e]437 return lt128(b.bin.hi, b.bin.lo, a.bin.hi, a.bin.lo);
[c67aff2]438}
439
[c0c38c7c]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
[231a60a]1149/** @}
[846848a6]1150 */
Note: See TracBrowser for help on using the repository browser.