1 /* Copyright (C) 2007 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 2, or (at your option) any later
10 In addition to the permissions in the GNU General Public License, the
11 Free Software Foundation gives you unlimited permission to link the
12 compiled version of this file into combinations with other programs,
13 and to distribute those combinations without any restriction coming
14 from the use of this file. (The General Public License restrictions
15 do apply in other respects; for example, they cover modification of
16 the file, and distribution when not linked into a combine
19 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 You should have received a copy of the GNU General Public License
25 along with GCC; see the file COPYING. If not, write to the Free
26 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
29 #include "bid_internal.h"
31 /*****************************************************************************
33 * BID128 non-computational functions:
36 * - bid128_isSubnormal
40 * - bid128_isSignaling
41 * - bid128_isCanonical
49 * - bid128_totalOrderMag
50 * - bid128_sameQuantum
52 ****************************************************************************/
54 #if DECIMAL_CALL_BY_REFERENCE
56 bid128_isSigned (int *pres
,
57 UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
61 bid128_isSigned (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
65 res
= ((x
.w
[HIGH_128W
] & MASK_SIGN
) == MASK_SIGN
);
69 // return 1 iff x is not zero, nor NaN nor subnormal nor infinity
70 #if DECIMAL_CALL_BY_REFERENCE
72 bid128_isNormal (int *pres
,
73 UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
77 bid128_isNormal (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
80 UINT64 x_exp
, C1_hi
, C1_lo
;
82 int exp
, q
, x_nr_bits
;
85 // test for special values - infinity or NaN
86 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
92 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
93 C1_hi
= x
.w
[1] & MASK_COEFF
;
96 if (C1_hi
== 0 && C1_lo
== 0) {
100 // test for non-canonical values of the argument x
101 if ((((C1_hi
> 0x0001ed09bead87c0ull
)
102 || ((C1_hi
== 0x0001ed09bead87c0ull
)
103 && (C1_lo
> 0x378d8e63ffffffffull
)))
104 && ((x
.w
[1] & 0x6000000000000000ull
) != 0x6000000000000000ull
))
105 || ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
109 // x is subnormal or normal
110 // determine the number of digits q in the significand
111 // q = nr. of decimal digits in x
112 // determine first the nr. of bits in x
114 if (C1_lo
>= 0x0020000000000000ull
) { // x >= 2^53
115 // split the 64-bit value in two 32-bit halves to avoid rounding errors
116 if (C1_lo
>= 0x0000000100000000ull
) { // x >= 2^32
117 tmp1
.d
= (double) (C1_lo
>> 32); // exact conversion
119 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
121 tmp1
.d
= (double) (C1_lo
); // exact conversion
123 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
125 } else { // if x < 2^53
126 tmp1
.d
= (double) C1_lo
; // exact conversion
128 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
130 } else { // C1_hi != 0 => nr. bits = 64 + nr_bits (C1_hi)
131 tmp1
.d
= (double) C1_hi
; // exact conversion
133 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
135 q
= nr_digits
[x_nr_bits
- 1].digits
;
137 q
= nr_digits
[x_nr_bits
- 1].digits1
;
138 if (C1_hi
> nr_digits
[x_nr_bits
- 1].threshold_hi
||
139 (C1_hi
== nr_digits
[x_nr_bits
- 1].threshold_hi
&&
140 C1_lo
>= nr_digits
[x_nr_bits
- 1].threshold_lo
))
143 exp
= (int) (x_exp
>> 49) - 6176;
144 // test for subnormal values of x
145 if (exp
+ q
<= -6143) {
154 // return 1 iff x is not zero, nor NaN nor normal nor infinity
155 #if DECIMAL_CALL_BY_REFERENCE
157 bid128_isSubnormal (int *pres
,
158 UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
162 bid128_isSubnormal (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
165 UINT64 x_exp
, C1_hi
, C1_lo
;
167 int exp
, q
, x_nr_bits
;
170 // test for special values - infinity or NaN
171 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
177 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
178 C1_hi
= x
.w
[1] & MASK_COEFF
;
181 if (C1_hi
== 0 && C1_lo
== 0) {
185 // test for non-canonical values of the argument x
186 if ((((C1_hi
> 0x0001ed09bead87c0ull
)
187 || ((C1_hi
== 0x0001ed09bead87c0ull
)
188 && (C1_lo
> 0x378d8e63ffffffffull
)))
189 && ((x
.w
[1] & 0x6000000000000000ull
) != 0x6000000000000000ull
))
190 || ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
194 // x is subnormal or normal
195 // determine the number of digits q in the significand
196 // q = nr. of decimal digits in x
197 // determine first the nr. of bits in x
199 if (C1_lo
>= 0x0020000000000000ull
) { // x >= 2^53
200 // split the 64-bit value in two 32-bit halves to avoid rounding errors
201 if (C1_lo
>= 0x0000000100000000ull
) { // x >= 2^32
202 tmp1
.d
= (double) (C1_lo
>> 32); // exact conversion
204 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
206 tmp1
.d
= (double) (C1_lo
); // exact conversion
208 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
210 } else { // if x < 2^53
211 tmp1
.d
= (double) C1_lo
; // exact conversion
213 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
215 } else { // C1_hi != 0 => nr. bits = 64 + nr_bits (C1_hi)
216 tmp1
.d
= (double) C1_hi
; // exact conversion
218 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
220 q
= nr_digits
[x_nr_bits
- 1].digits
;
222 q
= nr_digits
[x_nr_bits
- 1].digits1
;
223 if (C1_hi
> nr_digits
[x_nr_bits
- 1].threshold_hi
||
224 (C1_hi
== nr_digits
[x_nr_bits
- 1].threshold_hi
&&
225 C1_lo
>= nr_digits
[x_nr_bits
- 1].threshold_lo
))
228 exp
= (int) (x_exp
>> 49) - 6176;
229 // test for subnormal values of x
230 if (exp
+ q
<= -6143) {
238 #if DECIMAL_CALL_BY_REFERENCE
240 bid128_isFinite (int *pres
,
241 UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
245 bid128_isFinite (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
248 res
= ((x
.w
[HIGH_128W
] & MASK_INF
) != MASK_INF
);
252 #if DECIMAL_CALL_BY_REFERENCE
254 bid128_isZero (int *pres
, UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
258 bid128_isZero (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
264 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
268 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
270 if ((sig_x
.w
[1] > 0x0001ed09bead87c0ull
) || // significand is non-canonical
271 ((sig_x
.w
[1] == 0x0001ed09bead87c0ull
) && (sig_x
.w
[0] > 0x378d8e63ffffffffull
)) || // significand is non-canonical
272 ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
&& (x
.w
[1] & MASK_INF
) != MASK_INF
) || // significand is non-canonical
273 (sig_x
.w
[1] == 0 && sig_x
.w
[0] == 0)) { // significand is 0
281 #if DECIMAL_CALL_BY_REFERENCE
283 bid128_isInf (int *pres
, UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
287 bid128_isInf (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
290 res
= ((x
.w
[HIGH_128W
] & MASK_INF
) == MASK_INF
)
291 && ((x
.w
[HIGH_128W
] & MASK_NAN
) != MASK_NAN
);
295 #if DECIMAL_CALL_BY_REFERENCE
297 bid128_isSignaling (int *pres
,
298 UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
302 bid128_isSignaling (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
306 res
= ((x
.w
[HIGH_128W
] & MASK_SNAN
) == MASK_SNAN
);
310 // return 1 iff x is a canonical number ,infinity, or NaN.
311 #if DECIMAL_CALL_BY_REFERENCE
313 bid128_isCanonical (int *pres
,
314 UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
318 bid128_isCanonical (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
324 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // NaN
325 if (x
.w
[1] & 0x01ffc00000000000ull
) {
329 sig_x
.w
[1] = x
.w
[1] & 0x00003fffffffffffull
; // 46 bits
330 sig_x
.w
[0] = x
.w
[0]; // 64 bits
331 // payload must be < 10^33 = 0x0000314dc6448d93_38c15b0a00000000
332 if (sig_x
.w
[1] < 0x0000314dc6448d93ull
333 || (sig_x
.w
[1] == 0x0000314dc6448d93ull
334 && sig_x
.w
[0] < 0x38c15b0a00000000ull
)) {
340 } else if ((x
.w
[1] & MASK_INF
) == MASK_INF
) { // infinity
341 if ((x
.w
[1] & 0x03ffffffffffffffull
) || x
.w
[0]) {
348 // not NaN or infinity; extract significand to ensure it is canonical
349 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
351 // a canonical number has a coefficient < 10^34
352 // (0x0001ed09_bead87c0_378d8e64_00000000)
353 if ((sig_x
.w
[1] > 0x0001ed09bead87c0ull
) || // significand is non-canonical
354 ((sig_x
.w
[1] == 0x0001ed09bead87c0ull
) && (sig_x
.w
[0] > 0x378d8e63ffffffffull
)) || // significand is non-canonical
355 ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
363 #if DECIMAL_CALL_BY_REFERENCE
365 bid128_isNaN (int *pres
, UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
369 bid128_isNaN (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
373 res
= ((x
.w
[HIGH_128W
] & MASK_NAN
) == MASK_NAN
);
377 // copies a floating-point operand x to destination y, with no change
378 #if DECIMAL_CALL_BY_REFERENCE
380 bid128_copy (UINT128
* pres
,
381 UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
385 bid128_copy (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
393 // copies a floating-point operand x to destination y, reversing the sign
394 #if DECIMAL_CALL_BY_REFERENCE
396 bid128_negate (UINT128
* pres
,
397 UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
401 bid128_negate (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
405 x
.w
[HIGH_128W
] ^= MASK_SIGN
;
410 // copies a floating-point operand x to destination y, changing the sign to positive
411 #if DECIMAL_CALL_BY_REFERENCE
413 bid128_abs (UINT128
* pres
,
414 UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
418 bid128_abs (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
422 x
.w
[HIGH_128W
] &= ~MASK_SIGN
;
427 // copies operand x to destination in the same format as x, but with the sign of y
428 #if DECIMAL_CALL_BY_REFERENCE
430 bid128_copySign (UINT128
* pres
, UINT128
* px
,
431 UINT128
* py _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
436 bid128_copySign (UINT128 x
, UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
441 (x
.w
[HIGH_128W
] & ~MASK_SIGN
) | (y
.w
[HIGH_128W
] & MASK_SIGN
);
446 #if DECIMAL_CALL_BY_REFERENCE
448 bid128_class (int *pres
, UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
452 bid128_class (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
455 UINT256 sig_x_prime256
;
456 UINT192 sig_x_prime192
;
461 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) {
462 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) {
469 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
470 if ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) {
471 res
= negativeInfinity
;
473 res
= positiveInfinity
;
477 // decode number into exponent and significand
478 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
480 // check for zero or non-canonical
481 if ((sig_x
.w
[1] > 0x0001ed09bead87c0ull
)
482 || ((sig_x
.w
[1] == 0x0001ed09bead87c0ull
)
483 && (sig_x
.w
[0] > 0x378d8e63ffffffffull
))
484 || ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)
485 || ((sig_x
.w
[1] == 0) && (sig_x
.w
[0] == 0))) {
486 if ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) {
493 exp_x
= (x
.w
[1] >> 49) & 0x000000000003fffull
;
494 // if exponent is less than -6176, the number may be subnormal
495 // (less than the smallest normal value)
496 // the smallest normal value is 1 x 10^-6143 = 10^33 x 10^-6176
497 // if (exp_x - 6176 < -6143)
498 if (exp_x
< 33) { // sig_x * 10^exp_x
500 __mul_128x128_to_256 (sig_x_prime256
, sig_x
,
501 ten2k128
[exp_x
- 20]);
502 // 10^33 = 0x0000314dc6448d93_38c15b0a00000000
503 if ((sig_x_prime256
.w
[3] == 0) && (sig_x_prime256
.w
[2] == 0)
504 && ((sig_x_prime256
.w
[1] < 0x0000314dc6448d93ull
)
505 || ((sig_x_prime256
.w
[1] == 0x0000314dc6448d93ull
)
506 && (sig_x_prime256
.w
[0] < 0x38c15b0a00000000ull
)))) {
507 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? negativeSubnormal
:
512 __mul_64x128_to_192 (sig_x_prime192
, ten2k64
[exp_x
], sig_x
);
513 // 10^33 = 0x0000314dc6448d93_38c15b0a00000000
514 if ((sig_x_prime192
.w
[2] == 0)
515 && ((sig_x_prime192
.w
[1] < 0x0000314dc6448d93ull
)
516 || ((sig_x_prime192
.w
[1] == 0x0000314dc6448d93ull
)
517 && (sig_x_prime192
.w
[0] < 0x38c15b0a00000000ull
)))) {
518 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? negativeSubnormal
:
524 // otherwise, normal number, determine the sign
526 ((x
.w
[1] & MASK_SIGN
) ==
527 MASK_SIGN
) ? negativeNormal
: positiveNormal
;
531 // true if the exponents of x and y are the same, false otherwise.
532 // The special cases of sameQuantum(NaN, NaN) and sameQuantum(Inf, Inf) are true
533 // If exactly one operand is infinite or exactly one operand is NaN, then false
534 #if DECIMAL_CALL_BY_REFERENCE
536 bid128_sameQuantum (int *pres
, UINT128
* px
,
537 UINT128
* py _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
542 bid128_sameQuantum (UINT128 x
,
543 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
550 // if both operands are NaN, return true
551 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
552 || ((y
.w
[1] & MASK_NAN
) == MASK_NAN
)) {
553 res
= ((x
.w
[1] & MASK_NAN
) == MASK_NAN
554 && (y
.w
[1] & MASK_NAN
) == MASK_NAN
);
557 // if both operands are INF, return true
558 if ((x
.w
[1] & MASK_INF
) == MASK_INF
559 || (y
.w
[1] & MASK_INF
) == MASK_INF
) {
560 res
= ((x
.w
[1] & MASK_INF
) == MASK_INF
)
561 && ((y
.w
[1] & MASK_INF
) == MASK_INF
);
564 // decode exponents for both numbers, and return true if they match
565 if ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) { // G0_G1=11
566 x_exp
= (x
.w
[1] << 2) & MASK_EXP
; // biased and shifted left 49 bits
567 } else { // G0_G1 != 11
568 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bits
570 if ((y
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) { // G0_G1=11
571 y_exp
= (y
.w
[1] << 2) & MASK_EXP
; // biased and shifted left 49 bits
572 } else { // G0_G1 != 11
573 y_exp
= y
.w
[1] & MASK_EXP
; // biased and shifted left 49 bits
575 res
= (x_exp
== y_exp
);
579 #if DECIMAL_CALL_BY_REFERENCE
581 bid128_totalOrder (int *pres
, UINT128
* px
,
582 UINT128
* py _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
587 bid128_totalOrder (UINT128 x
,
588 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
592 UINT128 sig_x
, sig_y
, pyld_y
, pyld_x
;
593 UINT192 sig_n_prime192
;
594 UINT256 sig_n_prime256
;
595 char x_is_zero
= 0, y_is_zero
= 0;
600 // if x and y are unordered numerically because either operand is NaN
601 // (1) totalOrder(-NaN, number) is true
602 // (2) totalOrder(number, +NaN) is true
603 // (3) if x and y are both NaN:
604 // i) negative sign bit < positive sign bit
605 // ii) signaling < quiet for +NaN, reverse for -NaN
606 // iii) lesser payload < greater payload for +NaN (reverse for -NaN)
607 // iv) else if bitwise identical (in canonical form), return 1
608 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) {
610 if ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) {
611 // return true, unless y is -NaN also
612 if ((y
.w
[1] & MASK_NAN
) != MASK_NAN
613 || (y
.w
[1] & MASK_SIGN
) != MASK_SIGN
) {
614 res
= 1; // y is a number, return 1
616 } else { // if y and x are both -NaN
617 pyld_x
.w
[1] = x
.w
[1] & 0x00003fffffffffffull
;
618 pyld_x
.w
[0] = x
.w
[0];
619 pyld_y
.w
[1] = y
.w
[1] & 0x00003fffffffffffull
;
620 pyld_y
.w
[0] = y
.w
[0];
621 if ((pyld_x
.w
[1] > 0x0000314dc6448d93ull
)
622 || ((pyld_x
.w
[1] == 0x0000314dc6448d93ull
)
623 && (pyld_x
.w
[0] > 0x38c15b09ffffffffull
))) {
627 if ((pyld_y
.w
[1] > 0x0000314dc6448d93ull
)
628 || ((pyld_y
.w
[1] == 0x0000314dc6448d93ull
)
629 && (pyld_y
.w
[0] > 0x38c15b09ffffffffull
))) {
633 // if x and y are both -SNaN or both -QNaN, we have to compare payloads
634 // this statement evaluates to true if both are SNaN or QNaN
636 (((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) ^
637 ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
))) {
638 // it comes down to the payload. we want to return true if x has a
639 // larger payload, or if the payloads are equal (canonical forms
640 // are bitwise identical)
641 if ((pyld_x
.w
[1] > pyld_y
.w
[1]) ||
642 ((pyld_x
.w
[1] == pyld_y
.w
[1])
643 && (pyld_x
.w
[0] >= pyld_y
.w
[0])))
649 // either x = -SNaN and y = -QNaN or x = -QNaN and y = -SNaN
650 res
= ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
);
651 // totalOrder (-QNaN, -SNaN) == 1
655 } else { // x is +NaN
656 // return false, unless y is +NaN also
657 if ((y
.w
[1] & MASK_NAN
) != MASK_NAN
658 || (y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) {
659 res
= 0; // y is a number, return 1
662 // x and y are both +NaN;
663 pyld_x
.w
[1] = x
.w
[1] & 0x00003fffffffffffull
;
664 pyld_x
.w
[0] = x
.w
[0];
665 pyld_y
.w
[1] = y
.w
[1] & 0x00003fffffffffffull
;
666 pyld_y
.w
[0] = y
.w
[0];
667 if ((pyld_x
.w
[1] > 0x0000314dc6448d93ull
)
668 || ((pyld_x
.w
[1] == 0x0000314dc6448d93ull
)
669 && (pyld_x
.w
[0] > 0x38c15b09ffffffffull
))) {
673 if ((pyld_y
.w
[1] > 0x0000314dc6448d93ull
)
674 || ((pyld_y
.w
[1] == 0x0000314dc6448d93ull
)
675 && (pyld_y
.w
[0] > 0x38c15b09ffffffffull
))) {
679 // if x and y are both +SNaN or both +QNaN, we have to compare payloads
680 // this statement evaluates to true if both are SNaN or QNaN
682 (((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) ^
683 ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
))) {
684 // it comes down to the payload. we want to return true if x has a
685 // smaller payload, or if the payloads are equal (canonical forms
686 // are bitwise identical)
687 if ((pyld_x
.w
[1] < pyld_y
.w
[1]) ||
688 ((pyld_x
.w
[1] == pyld_y
.w
[1])
689 && (pyld_x
.w
[0] <= pyld_y
.w
[0])))
695 // either x = SNaN and y = QNaN or x = QNaN and y = SNaN
696 res
= ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
);
697 // totalOrder (-QNaN, -SNaN) == 1
702 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) {
703 // x is certainly not NAN in this case.
704 // return true if y is positive
705 res
= ((y
.w
[1] & MASK_SIGN
) != MASK_SIGN
);
709 // if all the bits are the same, the numbers are equal.
710 if ((x
.w
[1] == y
.w
[1]) && (x
.w
[0] == y
.w
[0])) {
714 // OPPOSITE SIGNS (CASE 3)
715 // if signs are opposite, return 1 if x is negative
716 // (if x < y, totalOrder is true)
717 if (((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ^ ((y
.w
[1] & MASK_SIGN
) ==
719 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
);
723 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
724 // if x == neg_inf, return (y == neg_inf);
725 if ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) {
729 // x is positive infinity, only return1 if y is positive infinity as well
730 res
= ((y
.w
[1] & MASK_INF
) == MASK_INF
);
732 // && (y & MASK_SIGN) != MASK_SIGN); (we know y has same sign as x)
734 } else if ((y
.w
[1] & MASK_INF
) == MASK_INF
) {
738 res
= ((y
.w
[1] & MASK_SIGN
) != MASK_SIGN
);
742 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
744 exp_x
= (x
.w
[1] >> 49) & 0x000000000003fffull
;
746 // CHECK IF x IS CANONICAL
747 // 9999999999999999999999999999999999 (decimal) =
748 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
749 // [0, 10^34) is the 754r supported canonical range.
750 // If the value exceeds that, it is interpreted as 0.
751 if ((((sig_x
.w
[1] > 0x0001ed09bead87c0ull
) ||
752 ((sig_x
.w
[1] == 0x0001ed09bead87c0ull
) &&
753 (sig_x
.w
[0] > 0x378d8e63ffffffffull
))) &&
754 ((x
.w
[1] & 0x6000000000000000ull
) != 0x6000000000000000ull
)) ||
755 ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) ||
756 ((sig_x
.w
[1] == 0) && (sig_x
.w
[0] == 0))) {
758 // check for the case where the exponent is shifted right by 2 bits!
759 if ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) {
760 exp_x
= (x
.w
[1] >> 47) & 0x000000000003fffull
;
764 exp_y
= (y
.w
[1] >> 49) & 0x0000000000003fffull
;
765 sig_y
.w
[1] = y
.w
[1] & 0x0001ffffffffffffull
;
768 // CHECK IF y IS CANONICAL
769 // 9999999999999999999999999999999999(decimal) =
770 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
771 // [0, 10^34) is the 754r supported canonical range.
772 // If the value exceeds that, it is interpreted as 0.
773 if ((((sig_y
.w
[1] > 0x0001ed09bead87c0ull
) ||
774 ((sig_y
.w
[1] == 0x0001ed09bead87c0ull
) &&
775 (sig_y
.w
[0] > 0x378d8e63ffffffffull
))) &&
776 ((y
.w
[1] & 0x6000000000000000ull
) != 0x6000000000000000ull
)) ||
777 ((y
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) ||
778 ((sig_y
.w
[1] == 0) && (sig_y
.w
[0] == 0))) {
780 // check for the case where the exponent is shifted right by 2 bits!
781 if ((y
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) {
782 exp_y
= (y
.w
[1] >> 47) & 0x000000000003fffull
;
786 // if x and y represent the same entities, and both are negative
787 // return true iff exp_x <= exp_y
788 if (x_is_zero
&& y_is_zero
) {
789 // we know that signs must be the same because we would have caught it
790 // in case3 if signs were different
791 // totalOrder(x,y) iff exp_x >= exp_y for negative numbers
792 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
793 if (exp_x
== exp_y
) {
797 res
= ((exp_x
<= exp_y
) ^ ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
));
800 // if x is zero and y isn't, clearly x has the smaller payload
802 res
= ((y
.w
[1] & MASK_SIGN
) != MASK_SIGN
);
805 // if y is zero, and x isn't, clearly y has the smaller payload
807 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
);
810 // REDUNDANT REPRESENTATIONS (CASE 6)
811 // if both components are either bigger or smaller
812 if (((sig_x
.w
[1] > sig_y
.w
[1])
813 || (sig_x
.w
[1] == sig_y
.w
[1] && sig_x
.w
[0] > sig_y
.w
[0]))
815 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
);
818 if (((sig_x
.w
[1] < sig_y
.w
[1])
819 || (sig_x
.w
[1] == sig_y
.w
[1] && sig_x
.w
[0] < sig_y
.w
[0]))
821 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
);
824 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
826 // if exp_x is 33 greater than exp_y, it is definitely larger,
827 // so no need for compensation
828 if (exp_x
- exp_y
> 33) {
829 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
);
831 // difference cannot be greater than 10^33
833 // otherwise adjust the x significand upwards
834 if (exp_x
- exp_y
> 19) {
835 __mul_128x128_to_256 (sig_n_prime256
, sig_x
,
836 ten2k128
[exp_x
- exp_y
- 20]);
837 // the compensated significands are equal (ie "x and y represent the same
838 // entities") return 1 if (negative && expx > expy) ||
839 // (positive && expx < expy)
840 if ((sig_n_prime256
.w
[3] == 0) && (sig_n_prime256
.w
[2] == 0)
841 && (sig_n_prime256
.w
[1] == sig_y
.w
[1])
842 && (sig_n_prime256
.w
[0] == sig_y
.w
[0])) {
843 // the case exp_x == exp_y cannot occur, because all bits must be
844 // the same - would have been caught if (x == y)
845 res
= ((exp_x
<= exp_y
) ^ ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
));
848 // if positive, return 1 if adjusted x is smaller than y
849 res
= (((sig_n_prime256
.w
[3] == 0) && (sig_n_prime256
.w
[2] == 0)
850 && ((sig_n_prime256
.w
[1] < sig_y
.w
[1])
851 || (sig_n_prime256
.w
[1] == sig_y
.w
[1]
852 && sig_n_prime256
.w
[0] <
853 sig_y
.w
[0]))) ^ ((x
.w
[1] & MASK_SIGN
) ==
857 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[exp_x
- exp_y
], sig_x
);
858 // if positive, return whichever significand is larger
859 // (converse if negative)
860 if ((sig_n_prime192
.w
[2] == 0) && sig_n_prime192
.w
[1] == sig_y
.w
[1]
861 && (sig_n_prime192
.w
[0] == sig_y
.w
[0])) {
862 res
= ((exp_x
<= exp_y
) ^ ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
));
865 res
= (((sig_n_prime192
.w
[2] == 0)
866 && ((sig_n_prime192
.w
[1] < sig_y
.w
[1])
867 || (sig_n_prime192
.w
[1] == sig_y
.w
[1]
868 && sig_n_prime192
.w
[0] <
869 sig_y
.w
[0]))) ^ ((x
.w
[1] & MASK_SIGN
) ==
873 // if exp_x is 33 less than exp_y, it is definitely smaller,
874 // no need for compensation
875 if (exp_y
- exp_x
> 33) {
876 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
);
879 if (exp_y
- exp_x
> 19) {
880 // adjust the y significand upwards
881 __mul_128x128_to_256 (sig_n_prime256
, sig_y
,
882 ten2k128
[exp_y
- exp_x
- 20]);
883 // if x and y represent the same entities and both are negative
884 // return true iff exp_x <= exp_y
885 if ((sig_n_prime256
.w
[3] == 0) && (sig_n_prime256
.w
[2] == 0)
886 && (sig_n_prime256
.w
[1] == sig_x
.w
[1])
887 && (sig_n_prime256
.w
[0] == sig_x
.w
[0])) {
888 res
= (exp_x
<= exp_y
) ^ ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
);
891 // values are not equal, for positive numbers return 1 if x is less than y
893 res
= (((sig_n_prime256
.w
[3] != 0) ||
894 // if upper128 bits of compensated y are non-zero, y is bigger
895 (sig_n_prime256
.w
[2] != 0) ||
896 // if upper128 bits of compensated y are non-zero, y is bigger
897 (sig_n_prime256
.w
[1] > sig_x
.w
[1]) ||
898 // if compensated y is bigger, y is bigger
899 (sig_n_prime256
.w
[1] == sig_x
.w
[1]
900 && sig_n_prime256
.w
[0] >
901 sig_x
.w
[0])) ^ ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
));
904 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[exp_y
- exp_x
], sig_y
);
905 if ((sig_n_prime192
.w
[2] == 0) && (sig_n_prime192
.w
[1] == sig_x
.w
[1])
906 && (sig_n_prime192
.w
[0] == sig_x
.w
[0])) {
907 res
= (exp_x
<= exp_y
) ^ ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
);
910 res
= (((sig_n_prime192
.w
[2] != 0) ||
911 // if upper128 bits of compensated y are non-zero, y is bigger
912 (sig_n_prime192
.w
[1] > sig_x
.w
[1]) ||
913 // if compensated y is bigger, y is bigger
914 (sig_n_prime192
.w
[1] == sig_x
.w
[1]
915 && sig_n_prime192
.w
[0] >
916 sig_x
.w
[0])) ^ ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
));
920 #if DECIMAL_CALL_BY_REFERENCE
922 bid128_totalOrderMag (int *pres
, UINT128
* px
,
923 UINT128
* py _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
928 bid128_totalOrderMag (UINT128 x
,
929 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
933 UINT128 sig_x
, sig_y
, pyld_y
, pyld_x
;
934 UINT192 sig_n_prime192
;
935 UINT256 sig_n_prime256
;
936 char x_is_zero
= 0, y_is_zero
= 0;
940 x
.w
[1] = x
.w
[1] & 0x7fffffffffffffffull
;
941 y
.w
[1] = y
.w
[1] & 0x7fffffffffffffffull
;
944 // if x and y are unordered numerically because either operand is NaN
945 // (1) totalOrder(number, +NaN) is true
946 // (2) if x and y are both NaN:
947 // i) signaling < quiet for +NaN
948 // ii) lesser payload < greater payload for +NaN
949 // iii) else if bitwise identical (in canonical form), return 1
950 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) {
952 // return false, unless y is +NaN also
953 if ((y
.w
[1] & MASK_NAN
) != MASK_NAN
) {
954 res
= 0; // y is a number, return 0
957 // x and y are both +NaN;
958 pyld_x
.w
[1] = x
.w
[1] & 0x00003fffffffffffull
;
959 pyld_x
.w
[0] = x
.w
[0];
960 pyld_y
.w
[1] = y
.w
[1] & 0x00003fffffffffffull
;
961 pyld_y
.w
[0] = y
.w
[0];
962 if ((pyld_x
.w
[1] > 0x0000314dc6448d93ull
)
963 || ((pyld_x
.w
[1] == 0x0000314dc6448d93ull
)
964 && (pyld_x
.w
[0] > 0x38c15b09ffffffffull
))) {
968 if ((pyld_y
.w
[1] > 0x0000314dc6448d93ull
)
969 || ((pyld_y
.w
[1] == 0x0000314dc6448d93ull
)
970 && (pyld_y
.w
[0] > 0x38c15b09ffffffffull
))) {
974 // if x and y are both +SNaN or both +QNaN, we have to compare payloads
975 // this statement evaluates to true if both are SNaN or QNaN
977 (((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) ^
978 ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
))) {
979 // it comes down to the payload. we want to return true if x has a
980 // smaller payload, or if the payloads are equal (canonical forms
981 // are bitwise identical)
982 if ((pyld_x
.w
[1] < pyld_y
.w
[1]) ||
983 ((pyld_x
.w
[1] == pyld_y
.w
[1])
984 && (pyld_x
.w
[0] <= pyld_y
.w
[0]))) {
991 // either x = SNaN and y = QNaN or x = QNaN and y = SNaN
992 res
= ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
);
993 // totalOrder (-QNaN, -SNaN) == 1
997 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) {
998 // x is certainly not NAN in this case.
999 // return true because y is positive
1004 // if all the bits are the same, the numbers are equal.
1005 if ((x
.w
[1] == y
.w
[1]) && (x
.w
[0] == y
.w
[0])) {
1009 // INFINITY (CASE 3)
1010 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
1011 // x is positive infinity, only return 1 if y is positive infinity as well
1012 res
= ((y
.w
[1] & MASK_INF
) == MASK_INF
);
1014 // (we know y has same sign as x)
1015 } else if ((y
.w
[1] & MASK_INF
) == MASK_INF
) {
1017 // since y is +inf, x<y
1025 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
1026 sig_x
.w
[0] = x
.w
[0];
1027 exp_x
= (x
.w
[1] >> 49) & 0x000000000003fffull
;
1029 // CHECK IF x IS CANONICAL
1030 // 9999999999999999999999999999999999 (decimal) =
1031 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1032 // [0, 10^34) is the 754r supported canonical range.
1033 // If the value exceeds that, it is interpreted as 0.
1034 if ((((sig_x
.w
[1] > 0x0001ed09bead87c0ull
) ||
1035 ((sig_x
.w
[1] == 0x0001ed09bead87c0ull
) &&
1036 (sig_x
.w
[0] > 0x378d8e63ffffffffull
))) &&
1037 ((x
.w
[1] & 0x6000000000000000ull
) != 0x6000000000000000ull
)) ||
1038 ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) ||
1039 ((sig_x
.w
[1] == 0) && (sig_x
.w
[0] == 0))) {
1041 // check for the case where the exponent is shifted right by 2 bits!
1042 if ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) {
1043 exp_x
= (x
.w
[1] >> 47) & 0x000000000003fffull
;
1047 exp_y
= (y
.w
[1] >> 49) & 0x0000000000003fffull
;
1048 sig_y
.w
[1] = y
.w
[1] & 0x0001ffffffffffffull
;
1049 sig_y
.w
[0] = y
.w
[0];
1051 // CHECK IF y IS CANONICAL
1052 // 9999999999999999999999999999999999(decimal) =
1053 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1054 // [0, 10^34) is the 754r supported canonical range.
1055 // If the value exceeds that, it is interpreted as 0.
1056 if ((((sig_y
.w
[1] > 0x0001ed09bead87c0ull
) ||
1057 ((sig_y
.w
[1] == 0x0001ed09bead87c0ull
) &&
1058 (sig_y
.w
[0] > 0x378d8e63ffffffffull
))) &&
1059 ((y
.w
[1] & 0x6000000000000000ull
) != 0x6000000000000000ull
)) ||
1060 ((y
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) ||
1061 ((sig_y
.w
[1] == 0) && (sig_y
.w
[0] == 0))) {
1063 // check for the case where the exponent is shifted right by 2 bits!
1064 if ((y
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) {
1065 exp_y
= (y
.w
[1] >> 47) & 0x000000000003fffull
;
1069 if (x_is_zero
&& y_is_zero
) {
1070 // we know that signs must be the same because we would have caught it
1071 // in case3 if signs were different
1072 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
1073 if (exp_x
== exp_y
) {
1077 res
= (exp_x
<= exp_y
);
1080 // if x is zero and y isn't, clearly x has the smaller payload
1085 // if y is zero, and x isn't, clearly y has the smaller payload
1090 // REDUNDANT REPRESENTATIONS (CASE 5)
1091 // if both components are either bigger or smaller
1092 if (((sig_x
.w
[1] > sig_y
.w
[1])
1093 || (sig_x
.w
[1] == sig_y
.w
[1] && sig_x
.w
[0] > sig_y
.w
[0]))
1094 && exp_x
>= exp_y
) {
1098 if (((sig_x
.w
[1] < sig_y
.w
[1])
1099 || (sig_x
.w
[1] == sig_y
.w
[1] && sig_x
.w
[0] < sig_y
.w
[0]))
1100 && exp_x
<= exp_y
) {
1104 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1105 if (exp_x
> exp_y
) {
1106 // if exp_x is 33 greater than exp_y, it is definitely larger,
1107 // so no need for compensation
1108 if (exp_x
- exp_y
> 33) {
1109 res
= 0; // difference cannot be greater than 10^33
1112 // otherwise adjust the x significand upwards
1113 if (exp_x
- exp_y
> 19) {
1114 __mul_128x128_to_256 (sig_n_prime256
, sig_x
,
1115 ten2k128
[exp_x
- exp_y
- 20]);
1116 // the compensated significands are equal (ie "x and y represent the same
1117 // entities") return 1 if (negative && expx > expy) ||
1118 // (positive && expx < expy)
1119 if ((sig_n_prime256
.w
[3] == 0) && (sig_n_prime256
.w
[2] == 0)
1120 && (sig_n_prime256
.w
[1] == sig_y
.w
[1])
1121 && (sig_n_prime256
.w
[0] == sig_y
.w
[0])) {
1122 // the case (exp_x == exp_y) cannot occur, because all bits must be
1123 // the same - would have been caught if (x == y)
1124 res
= (exp_x
<= exp_y
);
1127 // since positive, return 1 if adjusted x is smaller than y
1128 res
= ((sig_n_prime256
.w
[3] == 0) && (sig_n_prime256
.w
[2] == 0)
1129 && ((sig_n_prime256
.w
[1] < sig_y
.w
[1])
1130 || (sig_n_prime256
.w
[1] == sig_y
.w
[1]
1131 && sig_n_prime256
.w
[0] < sig_y
.w
[0])));
1134 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[exp_x
- exp_y
], sig_x
);
1135 // if positive, return whichever significand is larger
1136 // (converse if negative)
1137 if ((sig_n_prime192
.w
[2] == 0) && sig_n_prime192
.w
[1] == sig_y
.w
[1]
1138 && (sig_n_prime192
.w
[0] == sig_y
.w
[0])) {
1139 res
= (exp_x
<= exp_y
);
1142 res
= ((sig_n_prime192
.w
[2] == 0)
1143 && ((sig_n_prime192
.w
[1] < sig_y
.w
[1])
1144 || (sig_n_prime192
.w
[1] == sig_y
.w
[1]
1145 && sig_n_prime192
.w
[0] < sig_y
.w
[0])));
1148 // if exp_x is 33 less than exp_y, it is definitely smaller,
1149 // no need for compensation
1150 if (exp_y
- exp_x
> 33) {
1154 if (exp_y
- exp_x
> 19) {
1155 // adjust the y significand upwards
1156 __mul_128x128_to_256 (sig_n_prime256
, sig_y
,
1157 ten2k128
[exp_y
- exp_x
- 20]);
1158 if ((sig_n_prime256
.w
[3] == 0) && (sig_n_prime256
.w
[2] == 0)
1159 && (sig_n_prime256
.w
[1] == sig_x
.w
[1])
1160 && (sig_n_prime256
.w
[0] == sig_x
.w
[0])) {
1161 res
= (exp_x
<= exp_y
);
1164 // values are not equal, for positive numbers return 1 if x is less than y
1166 res
= ((sig_n_prime256
.w
[3] != 0) ||
1167 // if upper128 bits of compensated y are non-zero, y is bigger
1168 (sig_n_prime256
.w
[2] != 0) ||
1169 // if upper128 bits of compensated y are non-zero, y is bigger
1170 (sig_n_prime256
.w
[1] > sig_x
.w
[1]) ||
1171 // if compensated y is bigger, y is bigger
1172 (sig_n_prime256
.w
[1] == sig_x
.w
[1]
1173 && sig_n_prime256
.w
[0] > sig_x
.w
[0]));
1176 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[exp_y
- exp_x
], sig_y
);
1177 if ((sig_n_prime192
.w
[2] == 0) && (sig_n_prime192
.w
[1] == sig_x
.w
[1])
1178 && (sig_n_prime192
.w
[0] == sig_x
.w
[0])) {
1179 res
= (exp_x
<= exp_y
);
1182 res
= ((sig_n_prime192
.w
[2] != 0) ||
1183 // if upper128 bits of compensated y are non-zero, y is bigger
1184 (sig_n_prime192
.w
[1] > sig_x
.w
[1]) ||
1185 // if compensated y is bigger, y is bigger
1186 (sig_n_prime192
.w
[1] == sig_x
.w
[1]
1187 && sig_n_prime192
.w
[0] > sig_x
.w
[0]));
1191 #if DECIMAL_CALL_BY_REFERENCE
1193 bid128_radix (int *pres
, UINT128
* px _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
1197 bid128_radix (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
1200 if (x
.w
[LOW_128W
]) // dummy test