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
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;
[a35b458]192
[88d5c1e]193 and128(ld.bin.hi, ld.bin.lo,
[c67aff2]194 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
[a35b458]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;
[a35b458]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);
[a35b458]245
[c67aff2]246 /* a equals to b */
[88d5c1e]247 int are_equal = eq128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
[a35b458]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 */
[1b20da0]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 }
[a35b458]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 }
[a35b458]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 }
[a35b458]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 }
[a35b458]299
[88d5c1e]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;
[a35b458]321
[88d5c1e]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 }
[a35b458]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 }
[a35b458]335
[88d5c1e]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 */
[1b20da0]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 }
[a35b458]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 }
[a35b458]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 }
[a35b458]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 }
[a35b458]393
[88d5c1e]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;
[a35b458]415
[88d5c1e]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 }
[a35b458]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 }
[a35b458]429
[88d5c1e]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;
[a35b458]446
[c0c38c7c]447 float32_u ub;
448 ub.val = b;
[a35b458]449
[c0c38c7c]450 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
451 // TODO: sigNaNs
452 return -1;
453 }
[a35b458]454
[c0c38c7c]455 if (is_float32_gt(ua.data, ub.data))
456 return 1;
[a35b458]457
[c0c38c7c]458 return 0;
459}
460
461int __gesf2(float32_t a, float32_t b)
462{
463 float32_u ua;
464 ua.val = a;
[a35b458]465
[c0c38c7c]466 float32_u ub;
467 ub.val = b;
[a35b458]468
[c0c38c7c]469 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
470 // TODO: sigNaNs
471 return -1;
472 }
[a35b458]473
[c0c38c7c]474 if (is_float32_eq(ua.data, ub.data))
475 return 0;
[a35b458]476
[c0c38c7c]477 if (is_float32_gt(ua.data, ub.data))
478 return 1;
[a35b458]479
[c0c38c7c]480 return -1;
481}
482
483int __ltsf2(float32_t a, float32_t b)
484{
485 float32_u ua;
486 ua.val = a;
[a35b458]487
[c0c38c7c]488 float32_u ub;
489 ub.val = b;
[a35b458]490
[c0c38c7c]491 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
492 // TODO: sigNaNs
493 return 1;
494 }
[a35b458]495
[c0c38c7c]496 if (is_float32_lt(ua.data, ub.data))
497 return -1;
[a35b458]498
[c0c38c7c]499 return 0;
500}
501
502int __lesf2(float32_t a, float32_t b)
503{
504 float32_u ua;
505 ua.val = a;
[a35b458]506
[c0c38c7c]507 float32_u ub;
508 ub.val = b;
[a35b458]509
[c0c38c7c]510 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
511 // TODO: sigNaNs
512 return 1;
513 }
[a35b458]514
[c0c38c7c]515 if (is_float32_eq(ua.data, ub.data))
516 return 0;
[a35b458]517
[c0c38c7c]518 if (is_float32_lt(ua.data, ub.data))
519 return -1;
[a35b458]520
[c0c38c7c]521 return 1;
522}
523
524int __eqsf2(float32_t a, float32_t b)
525{
526 float32_u ua;
527 ua.val = a;
[a35b458]528
[c0c38c7c]529 float32_u ub;
530 ub.val = b;
[a35b458]531
[c0c38c7c]532 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
533 // TODO: sigNaNs
534 return 1;
535 }
[a35b458]536
[c0c38c7c]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;
[a35b458]550
[c0c38c7c]551 float32_u ub;
552 ub.val = b;
[a35b458]553
[c0c38c7c]554 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
555 /* No special constant for unordered - maybe signaled? */
556 return 1;
557 }
[a35b458]558
[c0c38c7c]559 if (is_float32_eq(ua.data, ub.data))
560 return 0;
[a35b458]561
[c0c38c7c]562 if (is_float32_lt(ua.data, ub.data))
563 return -1;
[a35b458]564
[c0c38c7c]565 return 1;
566}
567
568int __unordsf2(float32_t a, float32_t b)
569{
570 float32_u ua;
571 ua.val = a;
[a35b458]572
[c0c38c7c]573 float32_u ub;
574 ub.val = b;
[a35b458]575
[c0c38c7c]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;
[a35b458]583
[c0c38c7c]584 float32_u ub;
585 ub.val = b;
[a35b458]586
[c0c38c7c]587 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
588 // TODO: sigNaNs
589 return -1;
590 }
[a35b458]591
[c0c38c7c]592 if (is_float32_gt(ua.data, ub.data))
593 return 1;
[a35b458]594
[c0c38c7c]595 return 0;
596}
597
598int __aeabi_fcmplt(float32_t a, float32_t b)
599{
600 float32_u ua;
601 ua.val = a;
[a35b458]602
[c0c38c7c]603 float32_u ub;
604 ub.val = b;
[a35b458]605
[c0c38c7c]606 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
607 // TODO: sigNaNs
608 return 1;
609 }
[a35b458]610
[c0c38c7c]611 if (is_float32_lt(ua.data, ub.data))
612 return -1;
[a35b458]613
[c0c38c7c]614 return 0;
615}
616
617int __aeabi_fcmpge(float32_t a, float32_t b)
618{
619 float32_u ua;
620 ua.val = a;
[a35b458]621
[c0c38c7c]622 float32_u ub;
623 ub.val = b;
[a35b458]624
[c0c38c7c]625 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
626 // TODO: sigNaNs
627 return -1;
628 }
[a35b458]629
[c0c38c7c]630 if (is_float32_eq(ua.data, ub.data))
631 return 0;
[a35b458]632
[c0c38c7c]633 if (is_float32_gt(ua.data, ub.data))
634 return 1;
[a35b458]635
[c0c38c7c]636 return -1;
637}
638
639int __aeabi_fcmpeq(float32_t a, float32_t b)
640{
641 float32_u ua;
642 ua.val = a;
[a35b458]643
[c0c38c7c]644 float32_u ub;
645 ub.val = b;
[a35b458]646
[c0c38c7c]647 if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
648 // TODO: sigNaNs
649 return 1;
650 }
[a35b458]651
[c0c38c7c]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;
[a35b458]663
[c0c38c7c]664 float64_u ub;
665 ub.val = b;
[a35b458]666
[c0c38c7c]667 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
668 // TODO: sigNaNs
669 return -1;
670 }
[a35b458]671
[c0c38c7c]672 if (is_float64_gt(ua.data, ub.data))
673 return 1;
[a35b458]674
[c0c38c7c]675 return 0;
676}
677
678int __gedf2(float64_t a, float64_t b)
679{
680 float64_u ua;
681 ua.val = a;
[a35b458]682
[c0c38c7c]683 float64_u ub;
684 ub.val = b;
[a35b458]685
[c0c38c7c]686 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
687 // TODO: sigNaNs
688 return -1;
689 }
[a35b458]690
[c0c38c7c]691 if (is_float64_eq(ua.data, ub.data))
692 return 0;
[a35b458]693
[c0c38c7c]694 if (is_float64_gt(ua.data, ub.data))
695 return 1;
[a35b458]696
[c0c38c7c]697 return -1;
698}
699
700int __ltdf2(float64_t a, float64_t b)
701{
702 float64_u ua;
703 ua.val = a;
[a35b458]704
[c0c38c7c]705 float64_u ub;
706 ub.val = b;
[a35b458]707
[c0c38c7c]708 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
709 // TODO: sigNaNs
710 return 1;
711 }
[a35b458]712
[c0c38c7c]713 if (is_float64_lt(ua.data, ub.data))
714 return -1;
[a35b458]715
[c0c38c7c]716 return 0;
717}
718
719int __ledf2(float64_t a, float64_t b)
720{
721 float64_u ua;
722 ua.val = a;
[a35b458]723
[c0c38c7c]724 float64_u ub;
725 ub.val = b;
[a35b458]726
[c0c38c7c]727 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
728 // TODO: sigNaNs
729 return 1;
730 }
[a35b458]731
[c0c38c7c]732 if (is_float64_eq(ua.data, ub.data))
733 return 0;
[a35b458]734
[c0c38c7c]735 if (is_float64_lt(ua.data, ub.data))
736 return -1;
[a35b458]737
[c0c38c7c]738 return 1;
739}
740
741int __eqdf2(float64_t a, float64_t b)
742{
743 float64_u ua;
744 ua.val = a;
[a35b458]745
[c0c38c7c]746 float64_u ub;
747 ub.val = b;
[a35b458]748
[c0c38c7c]749 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
750 // TODO: sigNaNs
751 return 1;
752 }
[a35b458]753
[c0c38c7c]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;
[a35b458]767
[c0c38c7c]768 float64_u ub;
769 ub.val = b;
[a35b458]770
[c0c38c7c]771 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
772 /* No special constant for unordered - maybe signaled? */
773 return 1;
774 }
[a35b458]775
[c0c38c7c]776 if (is_float64_eq(ua.data, ub.data))
777 return 0;
[a35b458]778
[c0c38c7c]779 if (is_float64_lt(ua.data, ub.data))
780 return -1;
[a35b458]781
[c0c38c7c]782 return 1;
783}
784
785int __unorddf2(float64_t a, float64_t b)
786{
787 float64_u ua;
788 ua.val = a;
[a35b458]789
[c0c38c7c]790 float64_u ub;
791 ub.val = b;
[a35b458]792
[c0c38c7c]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;
[a35b458]800
[c0c38c7c]801 float64_u ub;
802 ub.val = b;
[a35b458]803
[c0c38c7c]804 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
805 // TODO: sigNaNs
806 return 1;
807 }
[a35b458]808
[c0c38c7c]809 if (is_float64_lt(ua.data, ub.data))
810 return -1;
[a35b458]811
[c0c38c7c]812 return 0;
813}
814
815int __aeabi_dcmpeq(float64_t a, float64_t b)
816{
817 float64_u ua;
818 ua.val = a;
[a35b458]819
[c0c38c7c]820 float64_u ub;
821 ub.val = b;
[a35b458]822
[c0c38c7c]823 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
824 // TODO: sigNaNs
825 return 1;
826 }
[a35b458]827
[c0c38c7c]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;
[a35b458]835
[c0c38c7c]836 float64_u ub;
837 ub.val = b;
[a35b458]838
[c0c38c7c]839 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
840 // TODO: sigNaNs
841 return -1;
842 }
[a35b458]843
[c0c38c7c]844 if (is_float64_gt(ua.data, ub.data))
845 return 1;
[a35b458]846
[c0c38c7c]847 return 0;
848}
849
850int __aeabi_dcmpge(float64_t a, float64_t b)
851{
852 float64_u ua;
853 ua.val = a;
[a35b458]854
[c0c38c7c]855 float64_u ub;
856 ub.val = b;
[a35b458]857
[c0c38c7c]858 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
859 // TODO: sigNaNs
860 return -1;
861 }
[a35b458]862
[c0c38c7c]863 if (is_float64_eq(ua.data, ub.data))
864 return 0;
[a35b458]865
[c0c38c7c]866 if (is_float64_gt(ua.data, ub.data))
867 return 1;
[a35b458]868
[c0c38c7c]869 return -1;
870}
871
872int __aeabi_dcmple(float64_t a, float64_t b)
873{
874 float64_u ua;
875 ua.val = a;
[a35b458]876
[c0c38c7c]877 float64_u ub;
878 ub.val = b;
[a35b458]879
[c0c38c7c]880 if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
881 // TODO: sigNaNs
882 return 1;
883 }
[a35b458]884
[c0c38c7c]885 if (is_float64_eq(ua.data, ub.data))
886 return 0;
[a35b458]887
[c0c38c7c]888 if (is_float64_lt(ua.data, ub.data))
889 return -1;
[a35b458]890
[c0c38c7c]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;
[a35b458]902
[c0c38c7c]903 float128_u ub;
904 ub.val = b;
[a35b458]905
[c0c38c7c]906 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
907 // TODO: sigNaNs
908 return -1;
909 }
[a35b458]910
[c0c38c7c]911 if (is_float128_gt(ua.data, ub.data))
912 return 1;
[a35b458]913
[c0c38c7c]914 return 0;
915}
916
917int __getf2(float128_t a, float128_t b)
918{
919 float128_u ua;
920 ua.val = a;
[a35b458]921
[c0c38c7c]922 float128_u ub;
923 ub.val = b;
[a35b458]924
[c0c38c7c]925 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
926 // TODO: sigNaNs
927 return -1;
928 }
[a35b458]929
[c0c38c7c]930 if (is_float128_eq(ua.data, ub.data))
931 return 0;
[a35b458]932
[c0c38c7c]933 if (is_float128_gt(ua.data, ub.data))
934 return 1;
[a35b458]935
[c0c38c7c]936 return -1;
937}
938
939int __lttf2(float128_t a, float128_t b)
940{
941 float128_u ua;
942 ua.val = a;
[a35b458]943
[c0c38c7c]944 float128_u ub;
945 ub.val = b;
[a35b458]946
[c0c38c7c]947 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
948 // TODO: sigNaNs
949 return 1;
950 }
[a35b458]951
[c0c38c7c]952 if (is_float128_lt(ua.data, ub.data))
953 return -1;
[a35b458]954
[c0c38c7c]955 return 0;
956}
957
958int __letf2(float128_t a, float128_t b)
959{
960 float128_u ua;
961 ua.val = a;
[a35b458]962
[c0c38c7c]963 float128_u ub;
964 ub.val = b;
[a35b458]965
[c0c38c7c]966 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
967 // TODO: sigNaNs
968 return 1;
969 }
[a35b458]970
[c0c38c7c]971 if (is_float128_eq(ua.data, ub.data))
972 return 0;
[a35b458]973
[c0c38c7c]974 if (is_float128_lt(ua.data, ub.data))
975 return -1;
[a35b458]976
[c0c38c7c]977 return 1;
978}
979
980int __eqtf2(float128_t a, float128_t b)
981{
982 float128_u ua;
983 ua.val = a;
[a35b458]984
[c0c38c7c]985 float128_u ub;
986 ub.val = b;
[a35b458]987
[c0c38c7c]988 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
989 // TODO: sigNaNs
990 return 1;
991 }
[a35b458]992
[c0c38c7c]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;
[a35b458]1006
[c0c38c7c]1007 float128_u ub;
1008 ub.val = b;
[a35b458]1009
[c0c38c7c]1010 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
1011 /* No special constant for unordered - maybe signaled? */
1012 return 1;
1013 }
[a35b458]1014
[c0c38c7c]1015 if (is_float128_eq(ua.data, ub.data))
1016 return 0;
[a35b458]1017
[c0c38c7c]1018 if (is_float128_lt(ua.data, ub.data))
1019 return -1;
[a35b458]1020
[c0c38c7c]1021 return 1;
1022}
1023
1024int __unordtf2(float128_t a, float128_t b)
1025{
1026 float128_u ua;
1027 ua.val = a;
[a35b458]1028
[c0c38c7c]1029 float128_u ub;
1030 ub.val = b;
[a35b458]1031
[c0c38c7c]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;
[a35b458]1039
[c0c38c7c]1040 float128_u ub;
1041 ub.val = *b;
[a35b458]1042
[c0c38c7c]1043 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1044 return 3;
[a35b458]1045
[c0c38c7c]1046 if (is_float128_eq(ua.data, ub.data))
1047 return 0;
[a35b458]1048
[c0c38c7c]1049 if (is_float128_lt(ua.data, ub.data))
1050 return 1;
[a35b458]1051
[c0c38c7c]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;
[a35b458]1065
[c0c38c7c]1066 float128_u ub;
1067 ub.val = *b;
[a35b458]1068
[c0c38c7c]1069 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1070 return 0;
[a35b458]1071
[c0c38c7c]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;
[a35b458]1079
[c0c38c7c]1080 float128_u ub;
1081 ub.val = *b;
[a35b458]1082
[c0c38c7c]1083 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1084 return 0;
[a35b458]1085
[c0c38c7c]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;
[a35b458]1094
[c0c38c7c]1095 float128_u ub;
1096 ub.val = *b;
[a35b458]1097
[c0c38c7c]1098 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1099 return 0;
[a35b458]1100
[c0c38c7c]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;
[a35b458]1108
[c0c38c7c]1109 float128_u ub;
1110 ub.val = *b;
[a35b458]1111
[c0c38c7c]1112 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1113 return 0;
[a35b458]1114
[c0c38c7c]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;
[a35b458]1123
[c0c38c7c]1124 float128_u ub;
1125 ub.val = *b;
[a35b458]1126
[c0c38c7c]1127 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1128 return 0;
[a35b458]1129
[c0c38c7c]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;
[a35b458]1137
[c0c38c7c]1138 float128_u ub;
1139 ub.val = *b;
[a35b458]1140
[c0c38c7c]1141 if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
1142 return 0;
[a35b458]1143
[c0c38c7c]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.