1 /* Copyright (C) 2007-2017 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
24 #include "bid_internal.h"
26 static const UINT64 mult_factor
[16] = {
27 1ull, 10ull, 100ull, 1000ull,
28 10000ull, 100000ull, 1000000ull, 10000000ull,
29 100000000ull, 1000000000ull, 10000000000ull, 100000000000ull,
30 1000000000000ull, 10000000000000ull,
31 100000000000000ull, 1000000000000000ull
34 /*****************************************************************************
35 * BID64 non-computational functions:
52 * - bid64_totalOrderMag
54 ****************************************************************************/
56 #if DECIMAL_CALL_BY_REFERENCE
58 bid64_isSigned (int *pres
, UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
62 bid64_isSigned (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
66 res
= ((x
& MASK_SIGN
) == MASK_SIGN
);
70 // return 1 iff x is not zero, nor NaN nor subnormal nor infinity
71 #if DECIMAL_CALL_BY_REFERENCE
73 bid64_isNormal (int *pres
, UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
77 bid64_isNormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
84 if ((x
& MASK_INF
) == MASK_INF
) { // x is either INF or NaN
87 // decode number into exponent and significand
88 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
89 sig_x
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
90 // check for zero or non-canonical
91 if (sig_x
> 9999999999999999ull || sig_x
== 0) {
92 res
= 0; // zero or non-canonical
95 exp_x
= (x
& MASK_BINARY_EXPONENT2
) >> 51;
97 sig_x
= (x
& MASK_BINARY_SIG1
);
102 exp_x
= (x
& MASK_BINARY_EXPONENT1
) >> 53;
104 // if exponent is less than -383, the number may be subnormal
105 // if (exp_x - 398 = -383) the number may be subnormal
107 __mul_64x64_to_128MACH (sig_x_prime
, sig_x
, mult_factor
[exp_x
]);
108 if (sig_x_prime
.w
[1] == 0
109 && sig_x_prime
.w
[0] < 1000000000000000ull) {
110 res
= 0; // subnormal
121 // return 1 iff x is not zero, nor NaN nor normal nor infinity
122 #if DECIMAL_CALL_BY_REFERENCE
124 bid64_isSubnormal (int *pres
,
125 UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
129 bid64_isSubnormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
136 if ((x
& MASK_INF
) == MASK_INF
) { // x is either INF or NaN
139 // decode number into exponent and significand
140 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
141 sig_x
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
142 // check for zero or non-canonical
143 if (sig_x
> 9999999999999999ull || sig_x
== 0) {
144 res
= 0; // zero or non-canonical
147 exp_x
= (x
& MASK_BINARY_EXPONENT2
) >> 51;
149 sig_x
= (x
& MASK_BINARY_SIG1
);
154 exp_x
= (x
& MASK_BINARY_EXPONENT1
) >> 53;
156 // if exponent is less than -383, the number may be subnormal
157 // if (exp_x - 398 = -383) the number may be subnormal
159 __mul_64x64_to_128MACH (sig_x_prime
, sig_x
, mult_factor
[exp_x
]);
160 if (sig_x_prime
.w
[1] == 0
161 && sig_x_prime
.w
[0] < 1000000000000000ull) {
162 res
= 1; // subnormal
173 //iff x is zero, subnormal or normal (not infinity or NaN)
174 #if DECIMAL_CALL_BY_REFERENCE
176 bid64_isFinite (int *pres
, UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
180 bid64_isFinite (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
184 res
= ((x
& MASK_INF
) != MASK_INF
);
188 #if DECIMAL_CALL_BY_REFERENCE
190 bid64_isZero (int *pres
, UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
194 bid64_isZero (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
198 // if infinity or nan, return 0
199 if ((x
& MASK_INF
) == MASK_INF
) {
201 } else if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
202 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1]
203 // => sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
204 // if(sig_x > 9999999999999999ull) {return 1;}
206 (((x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
) >
207 9999999999999999ull);
209 res
= ((x
& MASK_BINARY_SIG1
) == 0);
214 #if DECIMAL_CALL_BY_REFERENCE
216 bid64_isInf (int *pres
, UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
220 bid64_isInf (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
224 res
= ((x
& MASK_INF
) == MASK_INF
) && ((x
& MASK_NAN
) != MASK_NAN
);
228 #if DECIMAL_CALL_BY_REFERENCE
230 bid64_isSignaling (int *pres
,
231 UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
235 bid64_isSignaling (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
239 res
= ((x
& MASK_SNAN
) == MASK_SNAN
);
243 #if DECIMAL_CALL_BY_REFERENCE
245 bid64_isCanonical (int *pres
,
246 UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
250 bid64_isCanonical (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
254 if ((x
& MASK_NAN
) == MASK_NAN
) { // NaN
255 if (x
& 0x01fc000000000000ull
) {
257 } else if ((x
& 0x0003ffffffffffffull
) > 999999999999999ull) { // payload
262 } else if ((x
& MASK_INF
) == MASK_INF
) {
263 if (x
& 0x03ffffffffffffffull
) {
268 } else if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // 54-bit coeff.
270 (((x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
) <=
271 9999999999999999ull);
272 } else { // 53-bit coeff.
278 #if DECIMAL_CALL_BY_REFERENCE
280 bid64_isNaN (int *pres
, UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
284 bid64_isNaN (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
288 res
= ((x
& MASK_NAN
) == MASK_NAN
);
292 // copies a floating-point operand x to destination y, with no change
293 #if DECIMAL_CALL_BY_REFERENCE
295 bid64_copy (UINT64
* pres
, UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
299 bid64_copy (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
307 // copies a floating-point operand x to destination y, reversing the sign
308 #if DECIMAL_CALL_BY_REFERENCE
310 bid64_negate (UINT64
* pres
,
311 UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
315 bid64_negate (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
323 // copies a floating-point operand x to destination y, changing the sign to positive
324 #if DECIMAL_CALL_BY_REFERENCE
326 bid64_abs (UINT64
* pres
, UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
330 bid64_abs (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
334 res
= x
& ~MASK_SIGN
;
338 // copies operand x to destination in the same format as x, but
339 // with the sign of y
340 #if DECIMAL_CALL_BY_REFERENCE
342 bid64_copySign (UINT64
* pres
, UINT64
* px
,
343 UINT64
* py _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
348 bid64_copySign (UINT64 x
, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
352 res
= (x
& ~MASK_SIGN
) | (y
& MASK_SIGN
);
356 #if DECIMAL_CALL_BY_REFERENCE
358 bid64_class (int *pres
, UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
362 bid64_class (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
369 if ((x
& MASK_NAN
) == MASK_NAN
) {
370 // is the NaN signaling?
371 if ((x
& MASK_SNAN
) == MASK_SNAN
) {
375 // if NaN and not signaling, must be quietNaN
378 } else if ((x
& MASK_INF
) == MASK_INF
) {
379 // is the Infinity negative?
380 if ((x
& MASK_SIGN
) == MASK_SIGN
) {
381 res
= negativeInfinity
;
383 // otherwise, must be positive infinity
384 res
= positiveInfinity
;
387 } else if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
388 // decode number into exponent and significand
389 sig_x
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
390 // check for zero or non-canonical
391 if (sig_x
> 9999999999999999ull || sig_x
== 0) {
392 if ((x
& MASK_SIGN
) == MASK_SIGN
) {
399 exp_x
= (x
& MASK_BINARY_EXPONENT2
) >> 51;
401 sig_x
= (x
& MASK_BINARY_SIG1
);
404 ((x
& MASK_SIGN
) == MASK_SIGN
) ? negativeZero
: positiveZero
;
407 exp_x
= (x
& MASK_BINARY_EXPONENT1
) >> 53;
409 // if exponent is less than -383, number may be subnormal
410 // if (exp_x - 398 < -383)
411 if (exp_x
< 15) { // sig_x *10^exp_x
412 __mul_64x64_to_128MACH (sig_x_prime
, sig_x
, mult_factor
[exp_x
]);
413 if (sig_x_prime
.w
[1] == 0
414 && (sig_x_prime
.w
[0] < 1000000000000000ull)) {
417 MASK_SIGN
) ? negativeSubnormal
: positiveSubnormal
;
421 // otherwise, normal number, determine the sign
423 ((x
& MASK_SIGN
) == MASK_SIGN
) ? negativeNormal
: positiveNormal
;
427 // true if the exponents of x and y are the same, false otherwise.
428 // The special cases of sameQuantum (NaN, NaN) and sameQuantum (Inf, Inf) are
430 // If exactly one operand is infinite or exactly one operand is NaN, then false
431 #if DECIMAL_CALL_BY_REFERENCE
433 bid64_sameQuantum (int *pres
, UINT64
* px
,
434 UINT64
* py _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
439 bid64_sameQuantum (UINT64 x
, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
442 unsigned int exp_x
, exp_y
;
444 // if both operands are NaN, return true; if just one is NaN, return false
445 if ((x
& MASK_NAN
) == MASK_NAN
|| ((y
& MASK_NAN
) == MASK_NAN
)) {
446 res
= ((x
& MASK_NAN
) == MASK_NAN
&& (y
& MASK_NAN
) == MASK_NAN
);
449 // if both operands are INF, return true; if just one is INF, return false
450 if ((x
& MASK_INF
) == MASK_INF
|| (y
& MASK_INF
) == MASK_INF
) {
451 res
= ((x
& MASK_INF
) == MASK_INF
&& (y
& MASK_INF
) == MASK_INF
);
454 // decode exponents for both numbers, and return true if they match
455 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
456 exp_x
= (x
& MASK_BINARY_EXPONENT2
) >> 51;
458 exp_x
= (x
& MASK_BINARY_EXPONENT1
) >> 53;
460 if ((y
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
461 exp_y
= (y
& MASK_BINARY_EXPONENT2
) >> 51;
463 exp_y
= (y
& MASK_BINARY_EXPONENT1
) >> 53;
465 res
= (exp_x
== exp_y
);
469 #if DECIMAL_CALL_BY_REFERENCE
471 bid64_totalOrder (int *pres
, UINT64
* px
,
472 UINT64
* py _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
477 bid64_totalOrder (UINT64 x
, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
481 UINT64 sig_x
, sig_y
, pyld_y
, pyld_x
;
483 char x_is_zero
= 0, y_is_zero
= 0;
486 // if x and y are unordered numerically because either operand is NaN
487 // (1) totalOrder(-NaN, number) is true
488 // (2) totalOrder(number, +NaN) is true
489 // (3) if x and y are both NaN:
490 // i) negative sign bit < positive sign bit
491 // ii) signaling < quiet for +NaN, reverse for -NaN
492 // iii) lesser payload < greater payload for +NaN (reverse for -NaN)
493 // iv) else if bitwise identical (in canonical form), return 1
494 if ((x
& MASK_NAN
) == MASK_NAN
) {
496 if ((x
& MASK_SIGN
) == MASK_SIGN
) {
497 // return true, unless y is -NaN also
498 if ((y
& MASK_NAN
) != MASK_NAN
|| (y
& MASK_SIGN
) != MASK_SIGN
) {
499 res
= 1; // y is a number, return 1
501 } else { // if y and x are both -NaN
502 // if x and y are both -sNaN or both -qNaN, we have to compare payloads
503 // this xnor statement evaluates to true if both are sNaN or qNaN
505 (((y
& MASK_SNAN
) == MASK_SNAN
) ^ ((x
& MASK_SNAN
) ==
507 // it comes down to the payload. we want to return true if x has a
508 // larger payload, or if the payloads are equal (canonical forms
509 // are bitwise identical)
510 pyld_y
= y
& 0x0003ffffffffffffull
;
511 pyld_x
= x
& 0x0003ffffffffffffull
;
512 if (pyld_y
> 999999999999999ull || pyld_y
== 0) {
513 // if y is zero, x must be less than or numerically equal
518 // if x is zero and y isn't, x has the smaller payload
519 // definitely (since we know y isn't 0 at this point)
520 if (pyld_x
> 999999999999999ull || pyld_x
== 0) {
525 res
= (pyld_x
>= pyld_y
);
528 // either x = -sNaN and y = -qNaN or x = -qNaN and y = -sNaN
529 res
= (y
& MASK_SNAN
) == MASK_SNAN
; // totalOrder(-qNaN, -sNaN) == 1
533 } else { // x is +NaN
534 // return false, unless y is +NaN also
535 if ((y
& MASK_NAN
) != MASK_NAN
|| (y
& MASK_SIGN
) == MASK_SIGN
) {
536 res
= 0; // y is a number, return 1
539 // x and y are both +NaN;
540 // must investigate payload if both quiet or both signaling
541 // this xnor statement will be true if both x and y are +qNaN or +sNaN
543 (((y
& MASK_SNAN
) == MASK_SNAN
) ^ ((x
& MASK_SNAN
) ==
545 // it comes down to the payload. we want to return true if x has a
546 // smaller payload, or if the payloads are equal (canonical forms
547 // are bitwise identical)
548 pyld_y
= y
& 0x0003ffffffffffffull
;
549 pyld_x
= x
& 0x0003ffffffffffffull
;
550 // if x is zero and y isn't, x has the smaller
551 // payload definitely (since we know y isn't 0 at this point)
552 if (pyld_x
> 999999999999999ull || pyld_x
== 0) {
556 if (pyld_y
> 999999999999999ull || pyld_y
== 0) {
557 // if y is zero, x must be less than or numerically equal
561 res
= (pyld_x
<= pyld_y
);
564 // return true if y is +qNaN and x is +sNaN
565 // (we know they're different bc of xor if_stmt above)
566 res
= ((x
& MASK_SNAN
) == MASK_SNAN
);
571 } else if ((y
& MASK_NAN
) == MASK_NAN
) {
572 // x is certainly not NAN in this case.
573 // return true if y is positive
574 res
= ((y
& MASK_SIGN
) != MASK_SIGN
);
578 // if all the bits are the same, these numbers are equal.
583 // OPPOSITE SIGNS (CASE 3)
584 // if signs are opposite, return 1 if x is negative
585 // (if x<y, totalOrder is true)
586 if (((x
& MASK_SIGN
) == MASK_SIGN
) ^ ((y
& MASK_SIGN
) == MASK_SIGN
)) {
587 res
= (x
& MASK_SIGN
) == MASK_SIGN
;
591 if ((x
& MASK_INF
) == MASK_INF
) {
592 // if x==neg_inf, return (y == neg_inf)?1:0;
593 if ((x
& MASK_SIGN
) == MASK_SIGN
) {
597 // x is positive infinity, only return1 if y
598 // is positive infinity as well
599 // (we know y has same sign as x)
600 res
= ((y
& MASK_INF
) == MASK_INF
);
603 } else if ((y
& MASK_INF
) == MASK_INF
) {
607 res
= ((y
& MASK_SIGN
) != MASK_SIGN
);
610 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
611 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
612 exp_x
= (x
& MASK_BINARY_EXPONENT2
) >> 51;
613 sig_x
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
614 if (sig_x
> 9999999999999999ull || sig_x
== 0) {
618 exp_x
= (x
& MASK_BINARY_EXPONENT1
) >> 53;
619 sig_x
= (x
& MASK_BINARY_SIG1
);
625 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
626 if ((y
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
627 exp_y
= (y
& MASK_BINARY_EXPONENT2
) >> 51;
628 sig_y
= (y
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
629 if (sig_y
> 9999999999999999ull || sig_y
== 0) {
633 exp_y
= (y
& MASK_BINARY_EXPONENT1
) >> 53;
634 sig_y
= (y
& MASK_BINARY_SIG1
);
641 // if x and y represent the same entities, and
642 // both are negative , return true iff exp_x <= exp_y
643 if (x_is_zero
&& y_is_zero
) {
644 if (!((x
& MASK_SIGN
) == MASK_SIGN
) ^
645 ((y
& MASK_SIGN
) == MASK_SIGN
)) {
646 // if signs are the same:
647 // totalOrder(x,y) iff exp_x >= exp_y for negative numbers
648 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
649 if (exp_x
== exp_y
) {
653 res
= (exp_x
<= exp_y
) ^ ((x
& MASK_SIGN
) == MASK_SIGN
);
656 // signs are different.
657 // totalOrder(-0, +0) is true
658 // totalOrder(+0, -0) is false
659 res
= ((x
& MASK_SIGN
) == MASK_SIGN
);
663 // if x is zero and y isn't, clearly x has the smaller payload.
665 res
= ((y
& MASK_SIGN
) != MASK_SIGN
);
668 // if y is zero, and x isn't, clearly y has the smaller payload.
670 res
= ((x
& MASK_SIGN
) == MASK_SIGN
);
673 // REDUNDANT REPRESENTATIONS (CASE6)
674 // if both components are either bigger or smaller,
675 // it is clear what needs to be done
676 if (sig_x
> sig_y
&& exp_x
>= exp_y
) {
677 res
= ((x
& MASK_SIGN
) == MASK_SIGN
);
680 if (sig_x
< sig_y
&& exp_x
<= exp_y
) {
681 res
= ((x
& MASK_SIGN
) != MASK_SIGN
);
684 // if exp_x is 15 greater than exp_y, it is
685 // definitely larger, so no need for compensation
686 if (exp_x
- exp_y
> 15) {
687 // difference cannot be greater than 10^15
688 res
= ((x
& MASK_SIGN
) == MASK_SIGN
);
691 // if exp_x is 15 less than exp_y, it is
692 // definitely smaller, no need for compensation
693 if (exp_y
- exp_x
> 15) {
694 res
= ((x
& MASK_SIGN
) != MASK_SIGN
);
697 // if |exp_x - exp_y| < 15, it comes down
698 // to the compensated significand
700 // otherwise adjust the x significand upwards
701 __mul_64x64_to_128MACH (sig_n_prime
, sig_x
,
702 mult_factor
[exp_x
- exp_y
]);
703 // if x and y represent the same entities,
704 // and both are negative, return true iff exp_x <= exp_y
705 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_y
)) {
706 // case cannot occure, because all bits must
707 // be the same - would have been caught if (x==y)
708 res
= (exp_x
<= exp_y
) ^ ((x
& MASK_SIGN
) == MASK_SIGN
);
711 // if positive, return 1 if adjusted x is smaller than y
712 res
= ((sig_n_prime
.w
[1] == 0)
713 && sig_n_prime
.w
[0] < sig_y
) ^ ((x
& MASK_SIGN
) ==
717 // adjust the y significand upwards
718 __mul_64x64_to_128MACH (sig_n_prime
, sig_y
,
719 mult_factor
[exp_y
- exp_x
]);
721 // if x and y represent the same entities,
722 // and both are negative, return true iff exp_x <= exp_y
723 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_x
)) {
724 // Cannot occur, because all bits must be the same.
725 // Case would have been caught if (x==y)
726 res
= (exp_x
<= exp_y
) ^ ((x
& MASK_SIGN
) == MASK_SIGN
);
729 // values are not equal, for positive numbers return 1
730 // if x is less than y. 0 otherwise
731 res
= ((sig_n_prime
.w
[1] > 0)
732 || (sig_x
< sig_n_prime
.w
[0])) ^ ((x
& MASK_SIGN
) ==
737 // totalOrderMag is TotalOrder(abs(x), abs(y))
738 #if DECIMAL_CALL_BY_REFERENCE
740 bid64_totalOrderMag (int *pres
, UINT64
* px
,
741 UINT64
* py _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
746 bid64_totalOrderMag (UINT64 x
,
747 UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
751 UINT64 sig_x
, sig_y
, pyld_y
, pyld_x
;
753 char x_is_zero
= 0, y_is_zero
= 0;
756 // if x and y are unordered numerically because either operand is NaN
757 // (1) totalOrder(number, +NaN) is true
758 // (2) if x and y are both NaN:
759 // i) signaling < quiet for +NaN
760 // ii) lesser payload < greater payload for +NaN
761 // iii) else if bitwise identical (in canonical form), return 1
762 if ((x
& MASK_NAN
) == MASK_NAN
) {
765 // return false, unless y is +NaN also
766 if ((y
& MASK_NAN
) != MASK_NAN
) {
767 res
= 0; // y is a number, return 1
772 // x and y are both +NaN;
773 // must investigate payload if both quiet or both signaling
774 // this xnor statement will be true if both x and y are +qNaN or +sNaN
776 (((y
& MASK_SNAN
) == MASK_SNAN
) ^ ((x
& MASK_SNAN
) ==
778 // it comes down to the payload. we want to return true if x has a
779 // smaller payload, or if the payloads are equal (canonical forms
780 // are bitwise identical)
781 pyld_y
= y
& 0x0003ffffffffffffull
;
782 pyld_x
= x
& 0x0003ffffffffffffull
;
783 // if x is zero and y isn't, x has the smaller
784 // payload definitely (since we know y isn't 0 at this point)
785 if (pyld_x
> 999999999999999ull || pyld_x
== 0) {
790 if (pyld_y
> 999999999999999ull || pyld_y
== 0) {
791 // if y is zero, x must be less than or numerically equal
795 res
= (pyld_x
<= pyld_y
);
799 // return true if y is +qNaN and x is +sNaN
800 // (we know they're different bc of xor if_stmt above)
801 res
= ((x
& MASK_SNAN
) == MASK_SNAN
);
806 } else if ((y
& MASK_NAN
) == MASK_NAN
) {
807 // x is certainly not NAN in this case.
808 // return true if y is positive
813 // if all the bits (except sign bit) are the same,
814 // these numbers are equal.
815 if ((x
& ~MASK_SIGN
) == (y
& ~MASK_SIGN
)) {
820 if ((x
& MASK_INF
) == MASK_INF
) {
821 // x is positive infinity, only return1
822 // if y is positive infinity as well
823 res
= ((y
& MASK_INF
) == MASK_INF
);
825 } else if ((y
& MASK_INF
) == MASK_INF
) {
831 // if steering bits are 11 (condition will be 0),
832 // then exponent is G[0:w+1] =>
833 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
834 exp_x
= (x
& MASK_BINARY_EXPONENT2
) >> 51;
835 sig_x
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
836 if (sig_x
> 9999999999999999ull || sig_x
== 0) {
840 exp_x
= (x
& MASK_BINARY_EXPONENT1
) >> 53;
841 sig_x
= (x
& MASK_BINARY_SIG1
);
847 // if steering bits are 11 (condition will be 0),
848 // then exponent is G[0:w+1] =>
849 if ((y
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
850 exp_y
= (y
& MASK_BINARY_EXPONENT2
) >> 51;
851 sig_y
= (y
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
852 if (sig_y
> 9999999999999999ull || sig_y
== 0) {
856 exp_y
= (y
& MASK_BINARY_EXPONENT1
) >> 53;
857 sig_y
= (y
& MASK_BINARY_SIG1
);
864 // if x and y represent the same entities,
865 // and both are negative , return true iff exp_x <= exp_y
866 if (x_is_zero
&& y_is_zero
) {
867 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
868 res
= (exp_x
<= exp_y
);
871 // if x is zero and y isn't, clearly x has the smaller payload.
876 // if y is zero, and x isn't, clearly y has the smaller payload.
881 // REDUNDANT REPRESENTATIONS (CASE6)
882 // if both components are either bigger or smaller
883 if (sig_x
> sig_y
&& exp_x
>= exp_y
) {
887 if (sig_x
< sig_y
&& exp_x
<= exp_y
) {
891 // if exp_x is 15 greater than exp_y, it is definitely
892 // larger, so no need for compensation
893 if (exp_x
- exp_y
> 15) {
894 res
= 0; // difference cannot be greater than 10^15
897 // if exp_x is 15 less than exp_y, it is definitely
898 // smaller, no need for compensation
899 if (exp_y
- exp_x
> 15) {
903 // if |exp_x - exp_y| < 15, it comes down
904 // to the compensated significand
907 // otherwise adjust the x significand upwards
908 __mul_64x64_to_128MACH (sig_n_prime
, sig_x
,
909 mult_factor
[exp_x
- exp_y
]);
911 // if x and y represent the same entities,
912 // and both are negative, return true iff exp_x <= exp_y
913 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_y
)) {
914 // case cannot occur, because all bits
915 // must be the same - would have been caught if (x==y)
916 res
= (exp_x
<= exp_y
);
919 // if positive, return 1 if adjusted x is smaller than y
920 res
= ((sig_n_prime
.w
[1] == 0) && sig_n_prime
.w
[0] < sig_y
);
923 // adjust the y significand upwards
924 __mul_64x64_to_128MACH (sig_n_prime
, sig_y
,
925 mult_factor
[exp_y
- exp_x
]);
927 // if x and y represent the same entities,
928 // and both are negative, return true iff exp_x <= exp_y
929 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_x
)) {
930 res
= (exp_x
<= exp_y
);
933 // values are not equal, for positive numbers
934 // return 1 if x is less than y. 0 otherwise
935 res
= ((sig_n_prime
.w
[1] > 0) || (sig_x
< sig_n_prime
.w
[0]));
940 #if DECIMAL_CALL_BY_REFERENCE
942 bid64_radix (int *pres
, UINT64
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
946 bid64_radix (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {