2 * semi.c: test implementations of mathlib seminumerical functions
4 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 * See https://llvm.org/LICENSE.txt for license information.
6 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
12 static void test_rint(uint32
*in
, uint32
*out
,
13 int isfloor
, int isceil
) {
14 int sign
= in
[0] & 0x80000000;
15 int roundup
= (isfloor
&& sign
) || (isceil
&& !sign
);
16 uint32 xh
, xl
, roundword
;
17 int ex
= (in
[0] >> 20) & 0x7FF; /* exponent */
20 if ((ex
> 0x3ff + 52 - 1) || /* things this big can't be fractional */
21 ((in
[0] & 0x7FFFFFFF) == 0 && in
[1] == 0)) { /* zero */
22 /* NaN, Inf, a large integer, or zero: just return the input */
29 * Special case: ex < 0x3ff, ie our number is in (0,1). Return
30 * 1 or 0 according to roundup.
33 out
[0] = sign
| (roundup
? 0x3FF00000 : 0);
39 * We're not short of time here, so we'll do this the hideously
40 * inefficient way. Shift bit by bit so that the units place is
41 * somewhere predictable, round, and shift back again.
46 for (i
= ex
; i
< 0x3ff + 52; i
++) {
48 roundword
|= 2; /* preserve sticky bit */
49 roundword
= (roundword
>> 1) | ((xl
& 1) << 31);
50 xl
= (xl
>> 1) | ((xh
& 1) << 31);
53 if (roundword
&& roundup
) {
57 for (i
= ex
; i
< 0x3ff + 52; i
++) {
58 xh
= (xh
<< 1) | ((xl
>> 31) & 1);
59 xl
= (xl
& 0x7FFFFFFF) << 1;
65 char *test_ceil(uint32
*in
, uint32
*out
) {
66 test_rint(in
, out
, 0, 1);
70 char *test_floor(uint32
*in
, uint32
*out
) {
71 test_rint(in
, out
, 1, 0);
75 static void test_rintf(uint32
*in
, uint32
*out
,
76 int isfloor
, int isceil
) {
77 int sign
= *in
& 0x80000000;
78 int roundup
= (isfloor
&& sign
) || (isceil
&& !sign
);
80 int ex
= (*in
>> 23) & 0xFF; /* exponent */
83 if ((ex
> 0x7f + 23 - 1) || /* things this big can't be fractional */
84 (*in
& 0x7FFFFFFF) == 0) { /* zero */
85 /* NaN, Inf, a large integer, or zero: just return the input */
91 * Special case: ex < 0x7f, ie our number is in (0,1). Return
92 * 1 or 0 according to roundup.
95 *out
= sign
| (roundup
? 0x3F800000 : 0);
100 * We're not short of time here, so we'll do this the hideously
101 * inefficient way. Shift bit by bit so that the units place is
102 * somewhere predictable, round, and shift back again.
106 for (i
= ex
; i
< 0x7F + 23; i
++) {
108 roundword
|= 2; /* preserve sticky bit */
109 roundword
= (roundword
>> 1) | ((x
& 1) << 31);
112 if (roundword
&& roundup
) {
115 for (i
= ex
; i
< 0x7F + 23; i
++) {
121 char *test_ceilf(uint32
*in
, uint32
*out
) {
122 test_rintf(in
, out
, 0, 1);
126 char *test_floorf(uint32
*in
, uint32
*out
) {
127 test_rintf(in
, out
, 1, 0);
131 char *test_fmod(uint32
*a
, uint32
*b
, uint32
*out
) {
136 if (((a
[0] & 0x7FFFFFFF) << 1) + !!a
[1] > 0xFFE00000 ||
137 ((b
[0] & 0x7FFFFFFF) << 1) + !!b
[1] > 0xFFE00000) {
138 /* a or b is NaN: return QNaN, optionally with IVO */
142 an
= ((a
[0] & 0x7FFFFFFF) << 1) + !!a
[1];
143 bn
= ((b
[0] & 0x7FFFFFFF) << 1) + !!b
[1];
144 if ((an
> 0xFFE00000 && an
< 0xFFF00000) ||
145 (bn
> 0xFFE00000 && bn
< 0xFFF00000))
146 return "i"; /* at least one SNaN: IVO */
148 return NULL
; /* no SNaNs, but at least 1 QNaN */
150 if ((b
[0] & 0x7FFFFFFF) == 0 && b
[1] == 0) { /* b==0: EDOM */
153 return "EDOM status=i";
155 if ((a
[0] & 0x7FF00000) == 0x7FF00000) { /* a==Inf: EDOM */
158 return "EDOM status=i";
160 if ((b
[0] & 0x7FF00000) == 0x7FF00000) { /* b==Inf: return a */
165 if ((a
[0] & 0x7FFFFFFF) == 0 && a
[1] == 0) { /* a==0: return a */
172 * OK. That's the special cases cleared out of the way. Now we
173 * have finite (though not necessarily normal) a and b.
175 sign
= a
[0] & 0x80000000; /* we discard sign of b */
176 test_frexp(a
, am
, (uint32
*)&aex
);
177 test_frexp(b
, bm
, (uint32
*)&bex
);
178 am
[0] &= 0xFFFFF, am
[0] |= 0x100000;
179 bm
[0] &= 0xFFFFF, bm
[0] |= 0x100000;
182 if (am
[0] > bm
[0] || (am
[0] == bm
[0] && am
[1] >= bm
[1])) {
184 am
[0] = am
[0] - bm
[0] - (am
[1] > ~bm
[1]);
187 am
[0] = (am
[0] << 1) | ((am
[1] & 0x80000000) >> 31);
195 * Renormalise final result; this can be cunningly done by
196 * passing a denormal to ldexp.
200 test_ldexp(am
, (uint32
*)&aex
, out
);
202 return NULL
; /* FIXME */
205 char *test_fmodf(uint32
*a
, uint32
*b
, uint32
*out
) {
210 if ((*a
& 0x7FFFFFFF) > 0x7F800000 ||
211 (*b
& 0x7FFFFFFF) > 0x7F800000) {
212 /* a or b is NaN: return QNaN, optionally with IVO */
215 an
= *a
& 0x7FFFFFFF;
216 bn
= *b
& 0x7FFFFFFF;
217 if ((an
> 0x7f800000 && an
< 0x7fc00000) ||
218 (bn
> 0x7f800000 && bn
< 0x7fc00000))
219 return "i"; /* at least one SNaN: IVO */
221 return NULL
; /* no SNaNs, but at least 1 QNaN */
223 if ((*b
& 0x7FFFFFFF) == 0) { /* b==0: EDOM */
225 return "EDOM status=i";
227 if ((*a
& 0x7F800000) == 0x7F800000) { /* a==Inf: EDOM */
229 return "EDOM status=i";
231 if ((*b
& 0x7F800000) == 0x7F800000) { /* b==Inf: return a */
235 if ((*a
& 0x7FFFFFFF) == 0) { /* a==0: return a */
241 * OK. That's the special cases cleared out of the way. Now we
242 * have finite (though not necessarily normal) a and b.
244 sign
= a
[0] & 0x80000000; /* we discard sign of b */
245 test_frexpf(a
, &am
, (uint32
*)&aex
);
246 test_frexpf(b
, &bm
, (uint32
*)&bex
);
247 am
&= 0x7FFFFF, am
|= 0x800000;
248 bm
&= 0x7FFFFF, bm
|= 0x800000;
262 * Renormalise final result; this can be cunningly done by
263 * passing a denormal to ldexp.
267 test_ldexpf(&am
, (uint32
*)&aex
, out
);
269 return NULL
; /* FIXME */
272 char *test_ldexp(uint32
*x
, uint32
*np
, uint32
*out
) {
276 int ex
= (x
[0] >> 20) & 0x7FF; /* exponent */
277 int sign
= x
[0] & 0x80000000;
279 if (ex
== 0x7FF) { /* inf/NaN; just return x */
284 if ((x
[0] & 0x7FFFFFFF) == 0 && x
[1] == 0) { /* zero: return x */
290 test_frexp(x
, y
, (uint32
*)&n2
);
292 if (ex
> 0x400) { /* overflow */
293 out
[0] = sign
| 0x7FF00000;
298 * Underflow. 2^-1074 is 00000000.00000001; so if ex == -1074
299 * then we have something [2^-1075,2^-1074). Under round-to-
300 * nearest-even, this whole interval rounds up to 2^-1074,
301 * except for the bottom endpoint which rounds to even and is
302 * an underflow condition.
304 * So, ex < -1074 is definite underflow, and ex == -1074 is
305 * underflow iff all mantissa bits are zero.
307 if (ex
< -1074 || (ex
== -1074 && (y
[0] & 0xFFFFF) == 0 && y
[1] == 0)) {
308 out
[0] = sign
; /* underflow: correctly signed zero */
314 * No overflow or underflow; should be nice and simple, unless
315 * we have to denormalise and round the result.
317 if (ex
< -1021) { /* denormalise and round */
320 y
[0] |= 0x00100000; /* set leading bit */
324 roundword
|= 2; /* preserve sticky bit */
325 roundword
= (roundword
>> 1) | ((y
[1] & 1) << 31);
326 y
[1] = (y
[1] >> 1) | ((y
[0] & 1) << 31);
330 if (roundword
> 0x80000000 || /* round up */
331 (roundword
== 0x80000000 && (y
[1] & 1))) { /* round up to even */
335 out
[0] = sign
| y
[0];
337 /* Proper ERANGE underflow was handled earlier, but we still
338 * expect an IEEE Underflow exception if this partially
339 * underflowed result is not exact. */
342 return NULL
; /* underflow was handled earlier */
344 out
[0] = y
[0] + (ex
<< 20);
350 char *test_ldexpf(uint32
*x
, uint32
*np
, uint32
*out
) {
354 int ex
= (*x
>> 23) & 0xFF; /* exponent */
355 int sign
= *x
& 0x80000000;
357 if (ex
== 0xFF) { /* inf/NaN; just return x */
361 if ((*x
& 0x7FFFFFFF) == 0) { /* zero: return x */
366 test_frexpf(x
, &y
, (uint32
*)&n2
);
368 if (ex
> 0x80) { /* overflow */
369 *out
= sign
| 0x7F800000;
373 * Underflow. 2^-149 is 00000001; so if ex == -149 then we have
374 * something [2^-150,2^-149). Under round-to- nearest-even,
375 * this whole interval rounds up to 2^-149, except for the
376 * bottom endpoint which rounds to even and is an underflow
379 * So, ex < -149 is definite underflow, and ex == -149 is
380 * underflow iff all mantissa bits are zero.
382 if (ex
< -149 || (ex
== -149 && (y
& 0x7FFFFF) == 0)) {
383 *out
= sign
; /* underflow: correctly signed zero */
388 * No overflow or underflow; should be nice and simple, unless
389 * we have to denormalise and round the result.
391 if (ex
< -125) { /* denormalise and round */
394 y
|= 0x00800000; /* set leading bit */
398 roundword
|= 2; /* preserve sticky bit */
399 roundword
= (roundword
>> 1) | ((y
& 1) << 31);
403 if (roundword
> 0x80000000 || /* round up */
404 (roundword
== 0x80000000 && (y
& 1))) { /* round up to even */
408 /* Proper ERANGE underflow was handled earlier, but we still
409 * expect an IEEE Underflow exception if this partially
410 * underflowed result is not exact. */
413 return NULL
; /* underflow was handled earlier */
415 *out
= y
+ (ex
<< 23);
420 char *test_frexp(uint32
*x
, uint32
*out
, uint32
*nout
) {
421 int ex
= (x
[0] >> 20) & 0x7FF; /* exponent */
422 if (ex
== 0x7FF) { /* inf/NaN; return x/0 */
428 if (ex
== 0) { /* denormals/zeros */
431 if ((x
[0] & 0x7FFFFFFF) == 0 && x
[1] == 0) {
432 /* zero: return x/0 */
438 sign
= x
[0] & 0x80000000;
439 xh
= x
[0] & 0x7FFFFFFF;
442 while (!(xh
& 0x100000)) {
444 xh
= (xh
<< 1) | ((xl
>> 31) & 1);
445 xl
= (xl
& 0x7FFFFFFF) << 1;
447 out
[0] = sign
| 0x3FE00000 | (xh
& 0xFFFFF);
449 nout
[0] = ex
- 0x3FE;
452 out
[0] = 0x3FE00000 | (x
[0] & 0x800FFFFF);
454 nout
[0] = ex
- 0x3FE;
455 return NULL
; /* ordinary number; no error */
458 char *test_frexpf(uint32
*x
, uint32
*out
, uint32
*nout
) {
459 int ex
= (*x
>> 23) & 0xFF; /* exponent */
460 if (ex
== 0xFF) { /* inf/NaN; return x/0 */
465 if (ex
== 0) { /* denormals/zeros */
468 if ((*x
& 0x7FFFFFFF) == 0) {
469 /* zero: return x/0 */
474 sign
= *x
& 0x80000000;
475 xv
= *x
& 0x7FFFFFFF;
477 while (!(xv
& 0x800000)) {
481 *out
= sign
| 0x3F000000 | (xv
& 0x7FFFFF);
485 *out
= 0x3F000000 | (*x
& 0x807FFFFF);
487 return NULL
; /* ordinary number; no error */
490 char *test_modf(uint32
*x
, uint32
*fout
, uint32
*iout
) {
491 int ex
= (x
[0] >> 20) & 0x7FF; /* exponent */
492 int sign
= x
[0] & 0x80000000;
495 if (((x
[0] & 0x7FFFFFFF) | (!!x
[1])) > 0x7FF00000) {
497 * NaN input: return the same in _both_ outputs.
499 fout
[0] = iout
[0] = x
[0];
500 fout
[1] = iout
[1] = x
[1];
504 test_rint(x
, iout
, 0, 0);
507 if (!fh
&& !fl
) { /* no fraction part */
512 if (!(iout
[0] & 0x7FFFFFFF) && !iout
[1]) { /* no integer part */
517 while (!(fh
& 0x100000)) {
519 fh
= (fh
<< 1) | ((fl
>> 31) & 1);
520 fl
= (fl
& 0x7FFFFFFF) << 1;
522 fout
[0] = sign
| (ex
<< 20) | (fh
& 0xFFFFF);
527 char *test_modff(uint32
*x
, uint32
*fout
, uint32
*iout
) {
528 int ex
= (*x
>> 23) & 0xFF; /* exponent */
529 int sign
= *x
& 0x80000000;
532 if ((*x
& 0x7FFFFFFF) > 0x7F800000) {
534 * NaN input: return the same in _both_ outputs.
540 test_rintf(x
, iout
, 0, 0);
542 if (!f
) { /* no fraction part */
546 if (!(*iout
& 0x7FFFFFFF)) { /* no integer part */
550 while (!(f
& 0x800000)) {
554 *fout
= sign
| (ex
<< 23) | (f
& 0x7FFFFF);
558 char *test_copysign(uint32
*x
, uint32
*y
, uint32
*out
)
560 int ysign
= y
[0] & 0x80000000;
561 int xhigh
= x
[0] & 0x7fffffff;
563 out
[0] = ysign
| xhigh
;
566 /* There can be no error */
570 char *test_copysignf(uint32
*x
, uint32
*y
, uint32
*out
)
572 int ysign
= y
[0] & 0x80000000;
573 int xhigh
= x
[0] & 0x7fffffff;
575 out
[0] = ysign
| xhigh
;
577 /* There can be no error */
581 char *test_isfinite(uint32
*x
, uint32
*out
)
584 /* Being finite means that the exponent is not 0x7ff */
585 if ((xhigh
& 0x7ff00000) == 0x7ff00000) out
[0] = 0;
590 char *test_isfinitef(uint32
*x
, uint32
*out
)
592 /* Being finite means that the exponent is not 0xff */
593 if ((x
[0] & 0x7f800000) == 0x7f800000) out
[0] = 0;
598 char *test_isinff(uint32
*x
, uint32
*out
)
600 /* Being infinite means that our bottom 30 bits equate to 0x7f800000 */
601 if ((x
[0] & 0x7fffffff) == 0x7f800000) out
[0] = 1;
606 char *test_isinf(uint32
*x
, uint32
*out
)
610 /* Being infinite means that our fraction is zero and exponent is 0x7ff */
611 if (((xhigh
& 0x7fffffff) == 0x7ff00000) && (xlow
== 0)) out
[0] = 1;
616 char *test_isnanf(uint32
*x
, uint32
*out
)
618 /* Being NaN means that our exponent is 0xff and non-0 fraction */
619 int exponent
= x
[0] & 0x7f800000;
620 int fraction
= x
[0] & 0x007fffff;
621 if ((exponent
== 0x7f800000) && (fraction
!= 0)) out
[0] = 1;
626 char *test_isnan(uint32
*x
, uint32
*out
)
628 /* Being NaN means that our exponent is 0x7ff and non-0 fraction */
629 int exponent
= x
[0] & 0x7ff00000;
630 int fractionhigh
= x
[0] & 0x000fffff;
631 if ((exponent
== 0x7ff00000) && ((fractionhigh
!= 0) || x
[1] != 0))
637 char *test_isnormalf(uint32
*x
, uint32
*out
)
639 /* Being normal means exponent is not 0 and is not 0xff */
640 int exponent
= x
[0] & 0x7f800000;
641 if (exponent
== 0x7f800000) out
[0] = 0;
642 else if (exponent
== 0) out
[0] = 0;
647 char *test_isnormal(uint32
*x
, uint32
*out
)
649 /* Being normal means exponent is not 0 and is not 0x7ff */
650 int exponent
= x
[0] & 0x7ff00000;
651 if (exponent
== 0x7ff00000) out
[0] = 0;
652 else if (exponent
== 0) out
[0] = 0;
657 char *test_signbitf(uint32
*x
, uint32
*out
)
659 /* Sign bit is bit 31 */
660 out
[0] = (x
[0] >> 31) & 1;
664 char *test_signbit(uint32
*x
, uint32
*out
)
666 /* Sign bit is bit 31 */
667 out
[0] = (x
[0] >> 31) & 1;
671 char *test_fpclassify(uint32
*x
, uint32
*out
)
673 int exponent
= (x
[0] & 0x7ff00000) >> 20;
674 int fraction
= (x
[0] & 0x000fffff) | x
[1];
676 if ((exponent
== 0x00) && (fraction
== 0)) out
[0] = 0;
677 else if ((exponent
== 0x00) && (fraction
!= 0)) out
[0] = 4;
678 else if ((exponent
== 0x7ff) && (fraction
== 0)) out
[0] = 3;
679 else if ((exponent
== 0x7ff) && (fraction
!= 0)) out
[0] = 7;
684 char *test_fpclassifyf(uint32
*x
, uint32
*out
)
686 int exponent
= (x
[0] & 0x7f800000) >> 23;
687 int fraction
= x
[0] & 0x007fffff;
689 if ((exponent
== 0x000) && (fraction
== 0)) out
[0] = 0;
690 else if ((exponent
== 0x000) && (fraction
!= 0)) out
[0] = 4;
691 else if ((exponent
== 0xff) && (fraction
== 0)) out
[0] = 3;
692 else if ((exponent
== 0xff) && (fraction
!= 0)) out
[0] = 7;
698 * Internal function that compares doubles in x & y and returns -3, -2, -1, 0,
699 * 1 if they compare to be signaling, unordered, less than, equal or greater
702 static int fpcmp4(uint32
*x
, uint32
*y
)
707 * Sort out whether results are ordered or not to begin with
708 * NaNs have exponent 0x7ff, and non-zero fraction. Signaling NaNs take
709 * higher priority than quiet ones.
711 if ((x
[0] & 0x7fffffff) >= 0x7ff80000) result
= -2;
712 else if ((x
[0] & 0x7fffffff) > 0x7ff00000) result
= -3;
713 else if (((x
[0] & 0x7fffffff) == 0x7ff00000) && (x
[1] != 0)) result
= -3;
714 if ((y
[0] & 0x7fffffff) >= 0x7ff80000 && result
!= -3) result
= -2;
715 else if ((y
[0] & 0x7fffffff) > 0x7ff00000) result
= -3;
716 else if (((y
[0] & 0x7fffffff) == 0x7ff00000) && (y
[1] != 0)) result
= -3;
717 if (result
!= 0) return result
;
720 * The two forms of zero are equal
722 if (((x
[0] & 0x7fffffff) == 0) && x
[1] == 0 &&
723 ((y
[0] & 0x7fffffff) == 0) && y
[1] == 0)
727 * If x and y have different signs we can tell that they're not equal
728 * If x is +ve we have x > y return 1 - otherwise y is +ve return -1
730 if ((x
[0] >> 31) != (y
[0] >> 31))
731 return ((x
[0] >> 31) == 0) - ((y
[0] >> 31) == 0);
734 * Now we have both signs the same, let's do an initial compare of the
737 * Whoever designed IEEE754's floating point formats is very clever and
738 * earns my undying admiration. Once you remove the sign-bit, the
739 * floating point numbers can be ordered using the standard <, ==, >
740 * operators will treating the fp-numbers as integers with that bit-
743 if ((x
[0] & 0x7fffffff) < (y
[0] & 0x7fffffff)) result
= -1;
744 else if ((x
[0] & 0x7fffffff) > (y
[0] & 0x7fffffff)) result
= 1;
745 else if (x
[1] < y
[1]) result
= -1;
746 else if (x
[1] > y
[1]) result
= 1;
750 * Now we return the result - is x is positive (and therefore so is y) we
751 * return the plain result - otherwise we negate it and return.
753 if ((x
[0] >> 31) == 0) return result
;
758 * Internal function that compares floats in x & y and returns -3, -2, -1, 0,
759 * 1 if they compare to be signaling, unordered, less than, equal or greater
762 static int fpcmp4f(uint32
*x
, uint32
*y
)
767 * Sort out whether results are ordered or not to begin with
768 * NaNs have exponent 0xff, and non-zero fraction - we have to handle all
769 * signaling cases over the quiet ones
771 if ((x
[0] & 0x7fffffff) >= 0x7fc00000) result
= -2;
772 else if ((x
[0] & 0x7fffffff) > 0x7f800000) result
= -3;
773 if ((y
[0] & 0x7fffffff) >= 0x7fc00000 && result
!= -3) result
= -2;
774 else if ((y
[0] & 0x7fffffff) > 0x7f800000) result
= -3;
775 if (result
!= 0) return result
;
778 * The two forms of zero are equal
780 if (((x
[0] & 0x7fffffff) == 0) && ((y
[0] & 0x7fffffff) == 0))
784 * If x and y have different signs we can tell that they're not equal
785 * If x is +ve we have x > y return 1 - otherwise y is +ve return -1
787 if ((x
[0] >> 31) != (y
[0] >> 31))
788 return ((x
[0] >> 31) == 0) - ((y
[0] >> 31) == 0);
791 * Now we have both signs the same, let's do an initial compare of the
794 * Whoever designed IEEE754's floating point formats is very clever and
795 * earns my undying admiration. Once you remove the sign-bit, the
796 * floating point numbers can be ordered using the standard <, ==, >
797 * operators will treating the fp-numbers as integers with that bit-
800 if ((x
[0] & 0x7fffffff) < (y
[0] & 0x7fffffff)) result
= -1;
801 else if ((x
[0] & 0x7fffffff) > (y
[0] & 0x7fffffff)) result
= 1;
805 * Now we return the result - is x is positive (and therefore so is y) we
806 * return the plain result - otherwise we negate it and return.
808 if ((x
[0] >> 31) == 0) return result
;
812 char *test_isgreater(uint32
*x
, uint32
*y
, uint32
*out
)
814 int result
= fpcmp4(x
, y
);
815 *out
= (result
== 1);
816 return result
== -3 ? "i" : NULL
;
819 char *test_isgreaterequal(uint32
*x
, uint32
*y
, uint32
*out
)
821 int result
= fpcmp4(x
, y
);
822 *out
= (result
>= 0);
823 return result
== -3 ? "i" : NULL
;
826 char *test_isless(uint32
*x
, uint32
*y
, uint32
*out
)
828 int result
= fpcmp4(x
, y
);
829 *out
= (result
== -1);
830 return result
== -3 ? "i" : NULL
;
833 char *test_islessequal(uint32
*x
, uint32
*y
, uint32
*out
)
835 int result
= fpcmp4(x
, y
);
836 *out
= (result
== -1) || (result
== 0);
837 return result
== -3 ? "i" : NULL
;
840 char *test_islessgreater(uint32
*x
, uint32
*y
, uint32
*out
)
842 int result
= fpcmp4(x
, y
);
843 *out
= (result
== -1) || (result
== 1);
844 return result
== -3 ? "i" : NULL
;
847 char *test_isunordered(uint32
*x
, uint32
*y
, uint32
*out
)
850 int result
= fpcmp4(x
, y
);
852 test_isnormal(x
, out
);
854 test_isnormal(y
, out
);
856 *out
= (result
== -2) || (result
== -3);
857 return result
== -3 ? "i" : NULL
;
860 char *test_isgreaterf(uint32
*x
, uint32
*y
, uint32
*out
)
862 int result
= fpcmp4f(x
, y
);
863 *out
= (result
== 1);
864 return result
== -3 ? "i" : NULL
;
867 char *test_isgreaterequalf(uint32
*x
, uint32
*y
, uint32
*out
)
869 int result
= fpcmp4f(x
, y
);
870 *out
= (result
>= 0);
871 return result
== -3 ? "i" : NULL
;
874 char *test_islessf(uint32
*x
, uint32
*y
, uint32
*out
)
876 int result
= fpcmp4f(x
, y
);
877 *out
= (result
== -1);
878 return result
== -3 ? "i" : NULL
;
881 char *test_islessequalf(uint32
*x
, uint32
*y
, uint32
*out
)
883 int result
= fpcmp4f(x
, y
);
884 *out
= (result
== -1) || (result
== 0);
885 return result
== -3 ? "i" : NULL
;
888 char *test_islessgreaterf(uint32
*x
, uint32
*y
, uint32
*out
)
890 int result
= fpcmp4f(x
, y
);
891 *out
= (result
== -1) || (result
== 1);
892 return result
== -3 ? "i" : NULL
;
895 char *test_isunorderedf(uint32
*x
, uint32
*y
, uint32
*out
)
898 int result
= fpcmp4f(x
, y
);
900 test_isnormalf(x
, out
);
902 test_isnormalf(y
, out
);
904 *out
= (result
== -2) || (result
== -3);
905 return result
== -3 ? "i" : NULL
;