source: mainline/uspace/lib/softfloat/comparison.c@ 3bacee1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3bacee1 was 3212921, checked in by Jakub Jermar <jakub@…>, 7 years ago

Add aeabi_fcmple

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