source: mainline/uspace/lib/softfloat/comparison.c@ 7f7d642

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7f7d642 was 7c3fb9b, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix block comment formatting (ccheck).

  • Property mode set to 100644
File size: 22.6 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{
[7c3fb9b]87 /*
88 * SigNaN : exp = 0xff and fraction = 0xxxxx..x (binary),
89 * where at least one x is nonzero
90 */
[c67aff2]91 return ((f.parts.exp == 0xFF) &&
92 (f.parts.fraction < 0x400000) && (f.parts.fraction));
[e591928]93}
[b5440cf]94
[c67aff2]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 */
[88d5c1e]101int is_float64_signan(float64 d)
[750636a]102{
[7c3fb9b]103 /*
104 * SigNaN : exp = 0x7ff and fraction = 0xxxxx..x (binary),
105 * where at least one x is nonzero
106 */
[c67aff2]107 return ((d.parts.exp == 0x7FF) &&
108 (d.parts.fraction) && (d.parts.fraction < 0x8000000000000ll));
[e591928]109}
[feef1cd]110
[c67aff2]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 */
[88d5c1e]117int is_float128_signan(float128 ld)
[c67aff2]118{
[7c3fb9b]119 /*
120 * SigNaN : exp = 0x7fff and fraction = 0xxxxx..x (binary),
121 * where at least one x is nonzero
122 */
[c67aff2]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 */
[88d5c1e]135int is_float32_infinity(float32 f)
[7e557805]136{
[c67aff2]137 /* NaN : exp = 0x7ff and zero fraction */
[750636a]138 return ((f.parts.exp == 0xFF) && (f.parts.fraction == 0x0));
[e591928]139}
[7e557805]140
[c67aff2]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 */
[88d5c1e]147int is_float64_infinity(float64 d)
[feef1cd]148{
[c67aff2]149 /* NaN : exp = 0x7ff and zero fraction */
[750636a]150 return ((d.parts.exp == 0x7FF) && (d.parts.fraction == 0x0));
[e591928]151}
[feef1cd]152
[c67aff2]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 */
[88d5c1e]159int is_float128_infinity(float128 ld)
[c67aff2]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 */
[88d5c1e]172int is_float32_zero(float32 f)
[3af72dc]173{
[88d5c1e]174 return (((f.bin) & 0x7FFFFFFF) == 0);
[3af72dc]175}
176
[c67aff2]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 */
[88d5c1e]183int is_float64_zero(float64 d)
[feef1cd]184{
[88d5c1e]185 return (((d.bin) & 0x7FFFFFFFFFFFFFFFll) == 0);
[feef1cd]186}
187
[7e557805]188/**
[c67aff2]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 */
[88d5c1e]194int is_float128_zero(float128 ld)
[c67aff2]195{
196 uint64_t tmp_hi;
197 uint64_t tmp_lo;
[a35b458]198
[88d5c1e]199 and128(ld.bin.hi, ld.bin.lo,
[c67aff2]200 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
[a35b458]201
[c67aff2]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.
[7e557805]211 */
[88d5c1e]212int is_float32_eq(float32 a, float32 b)
[7e557805]213{
[750636a]214 /* a equals to b or both are zeros (with any sign) */
[88d5c1e]215 return ((a.bin == b.bin) ||
216 (((a.bin | b.bin) & 0x7FFFFFFF) == 0));
[c67aff2]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 */
[88d5c1e]226int is_float64_eq(float64 a, float64 b)
[c67aff2]227{
228 /* a equals to b or both are zeros (with any sign) */
[88d5c1e]229 return ((a.bin == b.bin) ||
230 (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0));
[c67aff2]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 */
[88d5c1e]240int is_float128_eq(float128 a, float128 b)
[c67aff2]241{
242 uint64_t tmp_hi;
243 uint64_t tmp_lo;
[a35b458]244
[c67aff2]245 /* both are zeros (with any sign) */
[88d5c1e]246 or128(a.bin.hi, a.bin.lo,
247 b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
[c67aff2]248 and128(tmp_hi, tmp_lo,
249 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
250 int both_zero = eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll);
[a35b458]251
[c67aff2]252 /* a equals to b */
[88d5c1e]253 int are_equal = eq128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
[a35b458]254
[c67aff2]255 return are_equal || both_zero;
[7e557805]256}
257
258/**
[c67aff2]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.
[7e557805]264 */
[1b20da0]265int is_float32_lt(float32 a, float32 b)
[7e557805]266{
[88d5c1e]267 if (((a.bin | b.bin) & 0x7FFFFFFF) == 0) {
268 /* +- zeroes */
269 return 0;
[c67aff2]270 }
[a35b458]271
[c67aff2]272 if ((a.parts.sign) && (b.parts.sign)) {
[750636a]273 /* if both are negative, smaller is that with greater binary value */
[88d5c1e]274 return (a.bin > b.bin);
[c67aff2]275 }
[a35b458]276
[88d5c1e]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 */
[750636a]282 a.parts.sign = !a.parts.sign;
283 b.parts.sign = !b.parts.sign;
[88d5c1e]284 return (a.bin < b.bin);
[7e557805]285}
286
[e649dfa]287/**
[c67aff2]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 */
[88d5c1e]294int is_float64_lt(float64 a, float64 b)
[c67aff2]295{
[88d5c1e]296 if (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0) {
297 /* +- zeroes */
298 return 0;
[c67aff2]299 }
[a35b458]300
[c67aff2]301 if ((a.parts.sign) && (b.parts.sign)) {
302 /* if both are negative, smaller is that with greater binary value */
[88d5c1e]303 return (a.bin > b.bin);
[c67aff2]304 }
[a35b458]305
[88d5c1e]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 */
[c67aff2]311 a.parts.sign = !a.parts.sign;
312 b.parts.sign = !b.parts.sign;
[88d5c1e]313 return (a.bin < b.bin);
[c67aff2]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 */
[88d5c1e]323int is_float128_lt(float128 a, float128 b)
[c67aff2]324{
325 uint64_t tmp_hi;
326 uint64_t tmp_lo;
[a35b458]327
[88d5c1e]328 or128(a.bin.hi, a.bin.lo,
329 b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
[c67aff2]330 and128(tmp_hi, tmp_lo,
331 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
332 if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
[88d5c1e]333 /* +- zeroes */
334 return 0;
[c67aff2]335 }
[a35b458]336
[c67aff2]337 if ((a.parts.sign) && (b.parts.sign)) {
338 /* if both are negative, smaller is that with greater binary value */
[88d5c1e]339 return lt128(b.bin.hi, b.bin.lo, a.bin.hi, a.bin.lo);
[c67aff2]340 }
[a35b458]341
[88d5c1e]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 */
[c67aff2]347 a.parts.sign = !a.parts.sign;
348 b.parts.sign = !b.parts.sign;
[88d5c1e]349 return lt128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
[c67aff2]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.
[e649dfa]358 */
[1b20da0]359int is_float32_gt(float32 a, float32 b)
[e649dfa]360{
[88d5c1e]361 if (((a.bin | b.bin) & 0x7FFFFFFF) == 0) {
362 /* zeroes are equal with any sign */
363 return 0;
[c67aff2]364 }
[a35b458]365
[c67aff2]366 if ((a.parts.sign) && (b.parts.sign)) {
[750636a]367 /* if both are negative, greater is that with smaller binary value */
[88d5c1e]368 return (a.bin < b.bin);
[c67aff2]369 }
[a35b458]370
[88d5c1e]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 */
[750636a]376 a.parts.sign = !a.parts.sign;
377 b.parts.sign = !b.parts.sign;
[88d5c1e]378 return (a.bin > b.bin);
[e649dfa]379}
380
[c67aff2]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 */
[88d5c1e]388int is_float64_gt(float64 a, float64 b)
[c67aff2]389{
[88d5c1e]390 if (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0) {
391 /* zeroes are equal with any sign */
392 return 0;
[c67aff2]393 }
[a35b458]394
[c67aff2]395 if ((a.parts.sign) && (b.parts.sign)) {
396 /* if both are negative, greater is that with smaller binary value */
[88d5c1e]397 return (a.bin < b.bin);
[c67aff2]398 }
[a35b458]399
[88d5c1e]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 */
[c67aff2]405 a.parts.sign = !a.parts.sign;
406 b.parts.sign = !b.parts.sign;
[88d5c1e]407 return (a.bin > b.bin);
[c67aff2]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 */
[88d5c1e]417int is_float128_gt(float128 a, float128 b)
[c67aff2]418{
419 uint64_t tmp_hi;
420 uint64_t tmp_lo;
[a35b458]421
[88d5c1e]422 or128(a.bin.hi, a.bin.lo,
423 b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
[c67aff2]424 and128(tmp_hi, tmp_lo,
425 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
426 if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
[88d5c1e]427 /* zeroes are equal with any sign */
428 return 0;
[c67aff2]429 }
[a35b458]430
[c67aff2]431 if ((a.parts.sign) && (b.parts.sign)) {
432 /* if both are negative, greater is that with smaller binary value */
[88d5c1e]433 return lt128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
[c67aff2]434 }
[a35b458]435
[88d5c1e]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 */
[c67aff2]441 a.parts.sign = !a.parts.sign;
442 b.parts.sign = !b.parts.sign;
[88d5c1e]443 return lt128(b.bin.hi, b.bin.lo, a.bin.hi, a.bin.lo);
[c67aff2]444}
445
[c0c38c7c]446#ifdef float32_t
447
448int __gtsf2(float32_t a, float32_t b)
449{
450 float32_u ua;
451 ua.val = a;
[a35b458]452
[c0c38c7c]453 float32_u ub;
454 ub.val = b;
[a35b458]455
[c0c38c7c]456 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
457 // TODO: sigNaNs
458 return -1;
459 }
[a35b458]460
[c0c38c7c]461 if (is_float32_gt(ua.data, ub.data))
462 return 1;
[a35b458]463
[c0c38c7c]464 return 0;
465}
466
467int __gesf2(float32_t a, float32_t b)
468{
469 float32_u ua;
470 ua.val = a;
[a35b458]471
[c0c38c7c]472 float32_u ub;
473 ub.val = b;
[a35b458]474
[c0c38c7c]475 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
476 // TODO: sigNaNs
477 return -1;
478 }
[a35b458]479
[c0c38c7c]480 if (is_float32_eq(ua.data, ub.data))
481 return 0;
[a35b458]482
[c0c38c7c]483 if (is_float32_gt(ua.data, ub.data))
484 return 1;
[a35b458]485
[c0c38c7c]486 return -1;
487}
488
489int __ltsf2(float32_t a, float32_t b)
490{
491 float32_u ua;
492 ua.val = a;
[a35b458]493
[c0c38c7c]494 float32_u ub;
495 ub.val = b;
[a35b458]496
[c0c38c7c]497 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
498 // TODO: sigNaNs
499 return 1;
500 }
[a35b458]501
[c0c38c7c]502 if (is_float32_lt(ua.data, ub.data))
503 return -1;
[a35b458]504
[c0c38c7c]505 return 0;
506}
507
508int __lesf2(float32_t a, float32_t b)
509{
510 float32_u ua;
511 ua.val = a;
[a35b458]512
[c0c38c7c]513 float32_u ub;
514 ub.val = b;
[a35b458]515
[c0c38c7c]516 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
517 // TODO: sigNaNs
518 return 1;
519 }
[a35b458]520
[c0c38c7c]521 if (is_float32_eq(ua.data, ub.data))
522 return 0;
[a35b458]523
[c0c38c7c]524 if (is_float32_lt(ua.data, ub.data))
525 return -1;
[a35b458]526
[c0c38c7c]527 return 1;
528}
529
530int __eqsf2(float32_t a, float32_t b)
531{
532 float32_u ua;
533 ua.val = a;
[a35b458]534
[c0c38c7c]535 float32_u ub;
536 ub.val = b;
[a35b458]537
[c0c38c7c]538 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
539 // TODO: sigNaNs
540 return 1;
541 }
[a35b458]542
[c0c38c7c]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;
[a35b458]556
[c0c38c7c]557 float32_u ub;
558 ub.val = b;
[a35b458]559
[c0c38c7c]560 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
561 /* No special constant for unordered - maybe signaled? */
562 return 1;
563 }
[a35b458]564
[c0c38c7c]565 if (is_float32_eq(ua.data, ub.data))
566 return 0;
[a35b458]567
[c0c38c7c]568 if (is_float32_lt(ua.data, ub.data))
569 return -1;
[a35b458]570
[c0c38c7c]571 return 1;
572}
573
574int __unordsf2(float32_t a, float32_t b)
575{
576 float32_u ua;
577 ua.val = a;
[a35b458]578
[c0c38c7c]579 float32_u ub;
580 ub.val = b;
[a35b458]581
[c0c38c7c]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;
[a35b458]589
[c0c38c7c]590 float32_u ub;
591 ub.val = b;
[a35b458]592
[c0c38c7c]593 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
594 // TODO: sigNaNs
[565aaff]595 return 0;
[c0c38c7c]596 }
[a35b458]597
[c0c38c7c]598 if (is_float32_gt(ua.data, ub.data))
599 return 1;
[a35b458]600
[c0c38c7c]601 return 0;
602}
603
604int __aeabi_fcmplt(float32_t a, float32_t b)
605{
606 float32_u ua;
607 ua.val = a;
[a35b458]608
[c0c38c7c]609 float32_u ub;
610 ub.val = b;
[a35b458]611
[c0c38c7c]612 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
613 // TODO: sigNaNs
[565aaff]614 return 0;
[c0c38c7c]615 }
[a35b458]616
[c0c38c7c]617 if (is_float32_lt(ua.data, ub.data))
[565aaff]618 return 1;
[a35b458]619
[c0c38c7c]620 return 0;
621}
622
623int __aeabi_fcmpge(float32_t a, float32_t b)
624{
625 float32_u ua;
626 ua.val = a;
[a35b458]627
[c0c38c7c]628 float32_u ub;
629 ub.val = b;
[a35b458]630
[c0c38c7c]631 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
632 // TODO: sigNaNs
[565aaff]633 return 0;
[c0c38c7c]634 }
[a35b458]635
[c0c38c7c]636 if (is_float32_eq(ua.data, ub.data))
[565aaff]637 return 1;
[a35b458]638
[c0c38c7c]639 if (is_float32_gt(ua.data, ub.data))
640 return 1;
[a35b458]641
[565aaff]642 return 0;
[c0c38c7c]643}
644
[3212921]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
[c0c38c7c]667int __aeabi_fcmpeq(float32_t a, float32_t b)
668{
669 float32_u ua;
670 ua.val = a;
[a35b458]671
[c0c38c7c]672 float32_u ub;
673 ub.val = b;
[a35b458]674
[c0c38c7c]675 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
676 // TODO: sigNaNs
[565aaff]677 return 0;
[c0c38c7c]678 }
[a35b458]679
[565aaff]680 return is_float32_eq(ua.data, ub.data);
[c0c38c7c]681}
682
683#endif
684
685#ifdef float64_t
686
687int __gtdf2(float64_t a, float64_t b)
688{
689 float64_u ua;
690 ua.val = a;
[a35b458]691
[c0c38c7c]692 float64_u ub;
693 ub.val = b;
[a35b458]694
[c0c38c7c]695 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
696 // TODO: sigNaNs
697 return -1;
698 }
[a35b458]699
[c0c38c7c]700 if (is_float64_gt(ua.data, ub.data))
701 return 1;
[a35b458]702
[c0c38c7c]703 return 0;
704}
705
706int __gedf2(float64_t a, float64_t b)
707{
708 float64_u ua;
709 ua.val = a;
[a35b458]710
[c0c38c7c]711 float64_u ub;
712 ub.val = b;
[a35b458]713
[c0c38c7c]714 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
715 // TODO: sigNaNs
716 return -1;
717 }
[a35b458]718
[c0c38c7c]719 if (is_float64_eq(ua.data, ub.data))
720 return 0;
[a35b458]721
[c0c38c7c]722 if (is_float64_gt(ua.data, ub.data))
723 return 1;
[a35b458]724
[c0c38c7c]725 return -1;
726}
727
728int __ltdf2(float64_t a, float64_t b)
729{
730 float64_u ua;
731 ua.val = a;
[a35b458]732
[c0c38c7c]733 float64_u ub;
734 ub.val = b;
[a35b458]735
[c0c38c7c]736 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
737 // TODO: sigNaNs
738 return 1;
739 }
[a35b458]740
[c0c38c7c]741 if (is_float64_lt(ua.data, ub.data))
742 return -1;
[a35b458]743
[c0c38c7c]744 return 0;
745}
746
747int __ledf2(float64_t a, float64_t b)
748{
749 float64_u ua;
750 ua.val = a;
[a35b458]751
[c0c38c7c]752 float64_u ub;
753 ub.val = b;
[a35b458]754
[c0c38c7c]755 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
756 // TODO: sigNaNs
757 return 1;
758 }
[a35b458]759
[c0c38c7c]760 if (is_float64_eq(ua.data, ub.data))
761 return 0;
[a35b458]762
[c0c38c7c]763 if (is_float64_lt(ua.data, ub.data))
764 return -1;
[a35b458]765
[c0c38c7c]766 return 1;
767}
768
769int __eqdf2(float64_t a, float64_t b)
770{
771 float64_u ua;
772 ua.val = a;
[a35b458]773
[c0c38c7c]774 float64_u ub;
775 ub.val = b;
[a35b458]776
[c0c38c7c]777 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
778 // TODO: sigNaNs
779 return 1;
780 }
[a35b458]781
[c0c38c7c]782 return is_float64_eq(ua.data, ub.data) - 1;
783}
784
785int __nedf2(float64_t a, float64_t b)
786{
787 /* Strange, but according to GCC documentation */
788 return __eqdf2(a, b);
789}
790
791int __cmpdf2(float64_t a, float64_t b)
792{
793 float64_u ua;
794 ua.val = a;
[a35b458]795
[c0c38c7c]796 float64_u ub;
797 ub.val = b;
[a35b458]798
[c0c38c7c]799 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
800 /* No special constant for unordered - maybe signaled? */
801 return 1;
802 }
[a35b458]803
[c0c38c7c]804 if (is_float64_eq(ua.data, ub.data))
805 return 0;
[a35b458]806
[c0c38c7c]807 if (is_float64_lt(ua.data, ub.data))
808 return -1;
[a35b458]809
[c0c38c7c]810 return 1;
811}
812
813int __unorddf2(float64_t a, float64_t b)
814{
815 float64_u ua;
816 ua.val = a;
[a35b458]817
[c0c38c7c]818 float64_u ub;
819 ub.val = b;
[a35b458]820
[c0c38c7c]821 return ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data)));
822}
823
824int __aeabi_dcmplt(float64_t a, float64_t b)
825{
826 float64_u ua;
827 ua.val = a;
[a35b458]828
[c0c38c7c]829 float64_u ub;
830 ub.val = b;
[a35b458]831
[c0c38c7c]832 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
833 // TODO: sigNaNs
[565aaff]834 return 0;
[c0c38c7c]835 }
[a35b458]836
[c0c38c7c]837 if (is_float64_lt(ua.data, ub.data))
[565aaff]838 return 1;
[a35b458]839
[c0c38c7c]840 return 0;
841}
842
843int __aeabi_dcmpeq(float64_t a, float64_t b)
844{
845 float64_u ua;
846 ua.val = a;
[a35b458]847
[c0c38c7c]848 float64_u ub;
849 ub.val = b;
[a35b458]850
[c0c38c7c]851 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
852 // TODO: sigNaNs
[565aaff]853 return 0;
[c0c38c7c]854 }
[a35b458]855
[565aaff]856 return is_float64_eq(ua.data, ub.data);
[c0c38c7c]857}
858
859int __aeabi_dcmpgt(float64_t a, float64_t b)
860{
861 float64_u ua;
862 ua.val = a;
[a35b458]863
[c0c38c7c]864 float64_u ub;
865 ub.val = b;
[a35b458]866
[c0c38c7c]867 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
868 // TODO: sigNaNs
[565aaff]869 return 0;
[c0c38c7c]870 }
[a35b458]871
[c0c38c7c]872 if (is_float64_gt(ua.data, ub.data))
873 return 1;
[a35b458]874
[c0c38c7c]875 return 0;
876}
877
878int __aeabi_dcmpge(float64_t a, float64_t b)
879{
880 float64_u ua;
881 ua.val = a;
[a35b458]882
[c0c38c7c]883 float64_u ub;
884 ub.val = b;
[a35b458]885
[c0c38c7c]886 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
887 // TODO: sigNaNs
[565aaff]888 return 0;
[c0c38c7c]889 }
[a35b458]890
[c0c38c7c]891 if (is_float64_eq(ua.data, ub.data))
[565aaff]892 return 1;
[a35b458]893
[c0c38c7c]894 if (is_float64_gt(ua.data, ub.data))
895 return 1;
[a35b458]896
[565aaff]897 return 0;
[c0c38c7c]898}
899
900int __aeabi_dcmple(float64_t a, float64_t b)
901{
902 float64_u ua;
903 ua.val = a;
[a35b458]904
[c0c38c7c]905 float64_u ub;
906 ub.val = b;
[a35b458]907
[c0c38c7c]908 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
909 // TODO: sigNaNs
[565aaff]910 return 0;
[c0c38c7c]911 }
[a35b458]912
[c0c38c7c]913 if (is_float64_eq(ua.data, ub.data))
[565aaff]914 return 1;
[a35b458]915
[c0c38c7c]916 if (is_float64_lt(ua.data, ub.data))
[565aaff]917 return 1;
[a35b458]918
[565aaff]919 return 0;
[c0c38c7c]920}
921
922#endif
923
924#ifdef float128_t
925
926int __gttf2(float128_t a, float128_t b)
927{
928 float128_u ua;
929 ua.val = a;
[a35b458]930
[c0c38c7c]931 float128_u ub;
932 ub.val = b;
[a35b458]933
[c0c38c7c]934 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
935 // TODO: sigNaNs
936 return -1;
937 }
[a35b458]938
[c0c38c7c]939 if (is_float128_gt(ua.data, ub.data))
940 return 1;
[a35b458]941
[c0c38c7c]942 return 0;
943}
944
945int __getf2(float128_t a, float128_t b)
946{
947 float128_u ua;
948 ua.val = a;
[a35b458]949
[c0c38c7c]950 float128_u ub;
951 ub.val = b;
[a35b458]952
[c0c38c7c]953 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
954 // TODO: sigNaNs
955 return -1;
956 }
[a35b458]957
[c0c38c7c]958 if (is_float128_eq(ua.data, ub.data))
959 return 0;
[a35b458]960
[c0c38c7c]961 if (is_float128_gt(ua.data, ub.data))
962 return 1;
[a35b458]963
[c0c38c7c]964 return -1;
965}
966
967int __lttf2(float128_t a, float128_t b)
968{
969 float128_u ua;
970 ua.val = a;
[a35b458]971
[c0c38c7c]972 float128_u ub;
973 ub.val = b;
[a35b458]974
[c0c38c7c]975 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
976 // TODO: sigNaNs
977 return 1;
978 }
[a35b458]979
[c0c38c7c]980 if (is_float128_lt(ua.data, ub.data))
981 return -1;
[a35b458]982
[c0c38c7c]983 return 0;
984}
985
986int __letf2(float128_t a, float128_t b)
987{
988 float128_u ua;
989 ua.val = a;
[a35b458]990
[c0c38c7c]991 float128_u ub;
992 ub.val = b;
[a35b458]993
[c0c38c7c]994 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
995 // TODO: sigNaNs
996 return 1;
997 }
[a35b458]998
[c0c38c7c]999 if (is_float128_eq(ua.data, ub.data))
1000 return 0;
[a35b458]1001
[c0c38c7c]1002 if (is_float128_lt(ua.data, ub.data))
1003 return -1;
[a35b458]1004
[c0c38c7c]1005 return 1;
1006}
1007
1008int __eqtf2(float128_t a, float128_t b)
1009{
1010 float128_u ua;
1011 ua.val = a;
[a35b458]1012
[c0c38c7c]1013 float128_u ub;
1014 ub.val = b;
[a35b458]1015
[c0c38c7c]1016 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
1017 // TODO: sigNaNs
1018 return 1;
1019 }
[a35b458]1020
[c0c38c7c]1021 return is_float128_eq(ua.data, ub.data) - 1;
1022}
1023
1024int __netf2(float128_t a, float128_t b)
1025{
1026 /* Strange, but according to GCC documentation */
1027 return __eqtf2(a, b);
1028}
1029
1030int __cmptf2(float128_t a, float128_t b)
1031{
1032 float128_u ua;
1033 ua.val = a;
[a35b458]1034
[c0c38c7c]1035 float128_u ub;
1036 ub.val = b;
[a35b458]1037
[c0c38c7c]1038 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
1039 /* No special constant for unordered - maybe signaled? */
1040 return 1;
1041 }
[a35b458]1042
[c0c38c7c]1043 if (is_float128_eq(ua.data, ub.data))
1044 return 0;
[a35b458]1045
[c0c38c7c]1046 if (is_float128_lt(ua.data, ub.data))
1047 return -1;
[a35b458]1048
[c0c38c7c]1049 return 1;
1050}
1051
1052int __unordtf2(float128_t a, float128_t b)
1053{
1054 float128_u ua;
1055 ua.val = a;
[a35b458]1056
[c0c38c7c]1057 float128_u ub;
1058 ub.val = b;
[a35b458]1059
[c0c38c7c]1060 return ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)));
1061}
1062
1063int _Qp_cmp(float128_t *a, float128_t *b)
1064{
1065 float128_u ua;
1066 ua.val = *a;
[a35b458]1067
[c0c38c7c]1068 float128_u ub;
1069 ub.val = *b;
[a35b458]1070
[c0c38c7c]1071 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1072 return 3;
[a35b458]1073
[c0c38c7c]1074 if (is_float128_eq(ua.data, ub.data))
1075 return 0;
[a35b458]1076
[c0c38c7c]1077 if (is_float128_lt(ua.data, ub.data))
1078 return 1;
[a35b458]1079
[c0c38c7c]1080 return 2;
1081}
1082
1083int _Qp_cmpe(float128_t *a, float128_t *b)
1084{
1085 /* Strange, but according to SPARC Compliance Definition */
1086 return _Qp_cmp(a, b);
1087}
1088
1089int _Qp_fgt(float128_t *a, float128_t *b)
1090{
1091 float128_u ua;
1092 ua.val = *a;
[a35b458]1093
[c0c38c7c]1094 float128_u ub;
1095 ub.val = *b;
[a35b458]1096
[c0c38c7c]1097 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1098 return 0;
[a35b458]1099
[c0c38c7c]1100 return is_float128_gt(ua.data, ub.data);
1101}
1102
1103int _Qp_fge(float128_t *a, float128_t *b)
1104{
1105 float128_u ua;
1106 ua.val = *a;
[a35b458]1107
[c0c38c7c]1108 float128_u ub;
1109 ub.val = *b;
[a35b458]1110
[c0c38c7c]1111 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1112 return 0;
[a35b458]1113
[c0c38c7c]1114 return is_float128_eq(ua.data, ub.data) ||
1115 is_float128_gt(ua.data, ub.data);
1116}
1117
1118int _Qp_flt(float128_t *a, float128_t *b)
1119{
1120 float128_u ua;
1121 ua.val = *a;
[a35b458]1122
[c0c38c7c]1123 float128_u ub;
1124 ub.val = *b;
[a35b458]1125
[c0c38c7c]1126 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1127 return 0;
[a35b458]1128
[c0c38c7c]1129 return is_float128_lt(ua.data, ub.data);
1130}
1131
1132int _Qp_fle(float128_t *a, float128_t *b)
1133{
1134 float128_u ua;
1135 ua.val = *a;
[a35b458]1136
[c0c38c7c]1137 float128_u ub;
1138 ub.val = *b;
[a35b458]1139
[c0c38c7c]1140 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1141 return 0;
[a35b458]1142
[c0c38c7c]1143 return is_float128_eq(ua.data, ub.data) ||
1144 is_float128_lt(ua.data, ub.data);
1145}
1146
1147int _Qp_feq(float128_t *a, float128_t *b)
1148{
1149 float128_u ua;
1150 ua.val = *a;
[a35b458]1151
[c0c38c7c]1152 float128_u ub;
1153 ub.val = *b;
[a35b458]1154
[c0c38c7c]1155 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1156 return 0;
[a35b458]1157
[c0c38c7c]1158 return is_float128_eq(ua.data, ub.data);
1159}
1160
1161int _Qp_fne(float128_t *a, float128_t *b)
1162{
1163 float128_u ua;
1164 ua.val = *a;
[a35b458]1165
[c0c38c7c]1166 float128_u ub;
1167 ub.val = *b;
[a35b458]1168
[c0c38c7c]1169 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1170 return 0;
[a35b458]1171
[c0c38c7c]1172 return !is_float128_eq(ua.data, ub.data);
1173}
1174
1175#endif
1176
[231a60a]1177/** @}
[846848a6]1178 */
Note: See TracBrowser for help on using the repository browser.