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
48 * - __bid128_totalOrder
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 = __bid_nr_digits[x_nr_bits - 1].digits;
137 q = __bid_nr_digits[x_nr_bits - 1].digits1;
138 if (C1_hi > __bid_nr_digits[x_nr_bits - 1].threshold_hi
139 || (C1_hi == __bid_nr_digits[x_nr_bits - 1].threshold_hi
140 && C1_lo >= __bid_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 = __bid_nr_digits[x_nr_bits - 1].digits;
222 q = __bid_nr_digits[x_nr_bits - 1].digits1;
223 if (C1_hi > __bid_nr_digits[x_nr_bits - 1].threshold_hi
224 || (C1_hi == __bid_nr_digits[x_nr_bits - 1].threshold_hi
225 && C1_lo >= __bid_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, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
244 __bid128_isFinite (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
247 res = ((x.w[HIGH_128W] & MASK_INF) != MASK_INF);
251 #if DECIMAL_CALL_BY_REFERENCE
253 __bid128_isZero (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
257 __bid128_isZero (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
263 if ((x.w[1] & MASK_INF) == MASK_INF) {
267 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
269 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) || // significand is non-canonical
270 ((sig_x.w[1] == 0x0001ed09bead87c0ull) &&
271 (sig_x.w[0] > 0x378d8e63ffffffffull)) || // significand is non-canonical
272 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull &&
273 (x.w[1] & MASK_INF) != MASK_INF) || // significand is non-canonical
274 (sig_x.w[1] == 0 && sig_x.w[0] == 0)) { // significand is 0
282 #if DECIMAL_CALL_BY_REFERENCE
284 __bid128_isInf (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
288 __bid128_isInf (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
291 res = ((x.w[HIGH_128W] & MASK_INF) == MASK_INF)
292 && ((x.w[HIGH_128W] & MASK_NAN) != MASK_NAN);
296 #if DECIMAL_CALL_BY_REFERENCE
298 __bid128_isSignaling (int *pres,
299 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
303 __bid128_isSignaling (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
307 res = ((x.w[HIGH_128W] & MASK_SNAN) == MASK_SNAN);
311 // return 1 iff x is a canonical number ,infinity, or NaN.
312 #if DECIMAL_CALL_BY_REFERENCE
314 __bid128_isCanonical (int *pres,
315 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
319 __bid128_isCanonical (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
325 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // NaN
326 if (x.w[1] & 0x01ffc00000000000ull) {
330 sig_x.w[1] = x.w[1] & 0x00003fffffffffffull; // 46 bits
331 sig_x.w[0] = x.w[0]; // 64 bits
332 // payload must be < 10^33 = 0x0000314dc6448d93_38c15b0a00000000
333 if (sig_x.w[1] < 0x0000314dc6448d93ull
334 || (sig_x.w[1] == 0x0000314dc6448d93ull
335 && sig_x.w[0] < 0x38c15b0a00000000ull)) {
341 } else if ((x.w[1] & MASK_INF) == MASK_INF) { // infinity
342 if ((x.w[1] & 0x03ffffffffffffffull) || x.w[0]) {
349 // not NaN or infinity; extract significand to ensure it is canonical
350 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
352 // a canonical number has a coefficient < 10^34
353 // (0x0001ed09_bead87c0_378d8e64_00000000)
354 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) || // significand is non-canonical
355 ((sig_x.w[1] == 0x0001ed09bead87c0ull) && (sig_x.w[0] > 0x378d8e63ffffffffull)) || // significand is non-canonical
356 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
364 #if DECIMAL_CALL_BY_REFERENCE
366 __bid128_isNaN (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
370 __bid128_isNaN (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
374 res = ((x.w[HIGH_128W] & MASK_NAN) == MASK_NAN);
378 // copies a floating-point operand x to destination y, with no change
379 #if DECIMAL_CALL_BY_REFERENCE
381 __bid128_copy (UINT128 * pres,
382 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
386 __bid128_copy (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
394 // copies a floating-point operand x to destination y, reversing the sign
395 #if DECIMAL_CALL_BY_REFERENCE
397 __bid128_negate (UINT128 * pres,
398 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
402 __bid128_negate (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
406 x.w[HIGH_128W] ^= MASK_SIGN;
411 // copies a floating-point operand x to destination y, changing the sign to positive
412 #if DECIMAL_CALL_BY_REFERENCE
414 __bid128_abs (UINT128 * pres,
415 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
419 __bid128_abs (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
423 x.w[HIGH_128W] &= ~MASK_SIGN;
428 // copies operand x to destination in the same format as x, but with the sign of y
429 #if DECIMAL_CALL_BY_REFERENCE
431 __bid128_copySign (UINT128 * pres, UINT128 * px,
432 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
437 __bid128_copySign (UINT128 x, UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
441 x.w[HIGH_128W] = (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 __bid_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)))) {
508 ((x.w[1] & MASK_SIGN) ==
509 MASK_SIGN) ? negativeSubnormal : positiveSubnormal;
513 __mul_64x128_to_192 (sig_x_prime192, __bid_ten2k64[exp_x], sig_x);
514 // 10^33 = 0x0000314dc6448d93_38c15b0a00000000
515 if ((sig_x_prime192.w[2] == 0)
516 && ((sig_x_prime192.w[1] < 0x0000314dc6448d93ull)
517 || ((sig_x_prime192.w[1] == 0x0000314dc6448d93ull)
518 && (sig_x_prime192.w[0] < 0x38c15b0a00000000ull)))) {
520 ((x.w[1] & MASK_SIGN) ==
521 MASK_SIGN) ? negativeSubnormal : positiveSubnormal;
526 // otherwise, normal number, determine the sign
528 ((x.w[1] & MASK_SIGN) ==
529 MASK_SIGN) ? negativeNormal : positiveNormal;
533 // true if the exponents of x and y are the same, false otherwise.
534 // The special cases of sameQuantum(NaN, NaN) and sameQuantum(Inf, Inf) are true
535 // If exactly one operand is infinite or exactly one operand is NaN, then false
536 #if DECIMAL_CALL_BY_REFERENCE
538 __bid128_sameQuantum (int *pres, UINT128 * px,
539 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
544 __bid128_sameQuantum (UINT128 x,
545 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
551 // if both operands are NaN, return true
552 if ((x.w[1] & MASK_NAN) == MASK_NAN
553 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
554 res = ((x.w[1] & MASK_NAN) == MASK_NAN
555 && (y.w[1] & MASK_NAN) == MASK_NAN);
558 // if both operands are INF, return true
559 if ((x.w[1] & MASK_INF) == MASK_INF
560 || (y.w[1] & MASK_INF) == MASK_INF) {
561 res = ((x.w[1] & MASK_INF) == MASK_INF)
562 && ((y.w[1] & MASK_INF) == MASK_INF);
565 // decode exponents for both numbers, and return true if they match
567 ((x.w[1] >> 49) & 0x0000000000003fffull) ==
568 ((y.w[1] >> 49) & 0x0000000000003fffull);
572 #if DECIMAL_CALL_BY_REFERENCE
574 __bid128_totalOrder (int *pres, UINT128 * px,
575 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
580 __bid128_totalOrder (UINT128 x,
581 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
585 UINT128 sig_x, sig_y, pyld_y, pyld_x;
586 UINT192 sig_n_prime192;
587 UINT256 sig_n_prime256;
588 char x_is_zero = 0, y_is_zero = 0;
593 // if x and y are unordered numerically because either operand is NaN
594 // (1) totalOrder(-NaN, number) is true
595 // (2) totalOrder(number, +NaN) is true
596 // (3) if x and y are both NaN:
597 // i) negative sign bit < positive sign bit
598 // ii) signaling < quiet fir +NaN, reverse for -NaN
599 // iii) lesser payload < greater payload for +NaN (reverse for -NaN)
600 if ((x.w[1] & MASK_NAN) == MASK_NAN) {
602 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) {
603 // return true, unless y is -NaN also
604 if ((y.w[1] & MASK_NAN) != MASK_NAN
605 || (y.w[1] & MASK_SIGN) != MASK_SIGN) {
606 res = 1; // y is a number, return 1
608 } else { // if y and x are both -NaN
609 // if x and y are both -SNaN or both -QNaN, we have to compare payloads
610 // this statement evaluates to true if both are SNaN or QNaN
612 (((y.w[1] & MASK_SNAN) ==
613 MASK_SNAN) ^ ((x.w[1] & MASK_SNAN) == MASK_SNAN))) {
614 // it comes down to the payload. we want to return true if x has a
615 // larger payload, but first we must calculate the payload.
616 pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull;
617 pyld_y.w[0] = y.w[0];
618 pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull;
619 pyld_x.w[0] = x.w[0];
620 if ((pyld_y.w[1] > 0x0000314dc6448d93ull)
621 || ((pyld_y.w[1] == 0x0000314dc6448d93ull)
622 && (pyld_y.w[0] > 0x38c15b09ffffffffull))
623 || (pyld_y.w[1] == 0 && pyld_y.w[0] == 0)) {
624 // if y is zero, x must be less than or numerically equal
629 // if x is zero and y isn't, x has the smaller payload
630 // definitely (since we know y isn't 0 at this point)
631 if ((pyld_x.w[1] > 0x0000314dc6448d93ull)
632 || ((pyld_x.w[1] == 0x0000314dc6448d93ull)
633 && (pyld_x.w[0] > 0x38c15b09ffffffffull))
634 || (pyld_x.w[0] == 0 && pyld_x.w[1] == 0)) {
639 res = ((pyld_x.w[1] > pyld_y.w[1])
640 || (pyld_x.w[1] == pyld_y.w[1]
641 && pyld_x.w[0] >= pyld_y.w[0]));
644 // either x = -SNaN and y = -QNaN or x = -QNaN and y = -SNaN
645 res = (y.w[1] & MASK_SNAN) == MASK_SNAN;
646 // totalOrder (-QNaN, -SNaN) == 1
650 } else { // x is +NaN
651 // return false, unless y is +NaN also
652 if ((y.w[1] & MASK_NAN) != MASK_NAN
653 || (y.w[1] & MASK_SIGN) == MASK_SIGN) {
654 res = 0; // y is a number, return 1
657 // x and y are both +NaN;
658 // must investigate payload if both quiet or both signaling
659 // this xnor statement will be true if both x and y are +QNaN or +SNaN
661 (((y.w[1] & MASK_SNAN) ==
662 MASK_SNAN) ^ ((x.w[1] & MASK_SNAN) == MASK_SNAN))) {
663 // it comes down to the payload. we want to return true if x has a
664 // smaller payload, but first we must calculate the payload.
665 pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull;
666 pyld_y.w[0] = y.w[0];
667 pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull;
668 pyld_x.w[0] = x.w[0];
669 // if x is zero and y isn't, x has the smaller payload definitely
670 // (since we know y isn't 0 at this point)
671 if ((pyld_x.w[1] > 0x0000314dc6448d93ull)
672 || ((pyld_x.w[1] == 0x0000314dc6448d93ull)
673 && (pyld_x.w[0] > 0x38c15b09ffffffffull))
674 || (pyld_x.w[1] == 0 && pyld_x.w[0] == 0)) {
678 if ((pyld_y.w[1] > 0x0000314dc6448d93ull)
679 || ((pyld_y.w[1] == 0x0000314dc6448d93ull)
680 && (pyld_y.w[0] > 0x38c15b09ffffffffull))
681 || (pyld_y.w[1] == 0 && pyld_y.w[0] == 0)) {
682 // if y is zero, x must be less than or numerically equal
686 res = ((pyld_x.w[1] < pyld_y.w[1])
687 || (pyld_x.w[1] == pyld_y.w[1]
688 && pyld_x.w[0] <= pyld_y.w[0]));
691 // return true if y is +QNaN and x is +SNaN
692 // (we know they're different bc of xor if_stmt above)
693 res = ((x.w[1] & MASK_SNAN) == MASK_SNAN);
698 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {
699 // x is certainly not NAN in this case.
700 // return true if y is positive
701 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
705 // if all the bits are the same, the numbers are equal.
706 if ((x.w[1] == y.w[1]) && (x.w[0] == y.w[0])) {
710 // OPPOSITE SIGNS (CASE 3)
711 // if signs are opposite, return 1 if x is negative
712 // (if x < y, totalOrder is true)
713 if (((x.w[1] & MASK_SIGN) == MASK_SIGN) ^
714 ((y.w[1] & MASK_SIGN) == MASK_SIGN)) {
715 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
719 if ((x.w[1] & MASK_INF) == MASK_INF) {
720 // if x == neg_inf, return (y == neg_inf);
721 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) {
725 // x is positive infinity, only return1 if y is positive infinity as well
726 res = ((y.w[1] & MASK_INF) == MASK_INF);
728 // && (y & MASK_SIGN) != MASK_SIGN); (we know y has same sign as x)
730 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
734 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
738 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
740 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
742 // CHECK IF x IS CANONICAL
743 // 9999999999999999999999999999999999 (decimal) =
744 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
745 // [0, 10^34) is the 754r supported canonical range.
746 // If the value exceeds that, it is interpreted as 0.
747 if ((((sig_x.w[1] > 0x0001ed09bead87c0ull) ||
748 ((sig_x.w[1] == 0x0001ed09bead87c0ull) &&
749 (sig_x.w[0] > 0x378d8e63ffffffffull))) &&
750 ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
751 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
752 ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
754 // check for the case where the exponent is shifted right by 2 bits!
755 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
756 exp_x = (x.w[1] >> 47) & 0x000000000003fffull;
760 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
761 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
764 // CHECK IF y IS CANONICAL
765 // 9999999999999999999999999999999999(decimal) =
766 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
767 // [0, 10^34) is the 754r supported canonical range.
768 // If the value exceeds that, it is interpreted as 0.
769 if ((((sig_y.w[1] > 0x0001ed09bead87c0ull) ||
770 ((sig_y.w[1] == 0x0001ed09bead87c0ull) &&
771 (sig_y.w[0] > 0x378d8e63ffffffffull))) &&
772 ((y.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
773 ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
774 ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
776 // check for the case where the exponent is shifted right by 2 bits!
777 if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
778 exp_y = (y.w[1] >> 47) & 0x000000000003fffull;
782 // if x and y represent the same entities, and both are negative
783 // return true iff exp_x <= exp_y
784 if (x_is_zero && y_is_zero) {
785 // we know that signs must be the same because we would have caught it
786 // in case3 if signs were different
787 // totalOrder(x,y) iff exp_x >= exp_y for negative numbers
788 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
789 if (exp_x == exp_y) {
793 res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
796 // if x is zero and y isn't, clearly x has the smaller payload
798 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
801 // if y is zero, and x isn't, clearly y has the smaller payload
803 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
806 // REDUNDANT REPRESENTATIONS (CASE 6)
807 // if both components are either bigger or smaller
808 if (((sig_x.w[1] > sig_y.w[1])
809 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
811 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
814 if (((sig_x.w[1] < sig_y.w[1])
815 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
817 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
820 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
822 // if exp_x is 33 greater than exp_y, it is definitely larger,
823 // so no need for compensation
824 if (exp_x - exp_y > 33) {
825 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
827 // difference cannot be greater than 10^33
829 // otherwise adjust the x significand upwards
830 if (exp_x - exp_y > 19) {
831 __mul_128x128_to_256 (sig_n_prime256, sig_x,
832 __bid_ten2k128[exp_x - exp_y - 20]);
833 // the compensated significands are equal (ie "x and y represent the same
834 // entities") return 1 if (negative && expx > expy) ||
835 // (positive && expx < expy)
836 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
837 && (sig_n_prime256.w[1] == sig_y.w[1])
838 && (sig_n_prime256.w[0] == sig_y.w[0])) {
839 // the case exp_x == exp_y cannot occur, because all bits must be
840 // the same - would have been caught if (x == y)
841 res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
844 // if positive, return 1 if adjusted x is smaller than y
845 res = (((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
846 && ((sig_n_prime256.w[1] < sig_y.w[1])
847 || (sig_n_prime256.w[1] == sig_y.w[1]
848 && sig_n_prime256.w[0] <
849 sig_y.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
853 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[exp_x - exp_y], sig_x);
854 // if positive, return whichever significand is larger
855 // (converse if negative)
856 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
857 && (sig_n_prime192.w[0] == sig_y.w[0])) {
858 res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
861 res = (((sig_n_prime192.w[2] == 0)
862 && ((sig_n_prime192.w[1] < sig_y.w[1])
863 || (sig_n_prime192.w[1] == sig_y.w[1]
864 && sig_n_prime192.w[0] <
865 sig_y.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
869 // if exp_x is 33 less than exp_y, it is definitely smaller,
870 // no need for compensation
871 if (exp_y - exp_x > 33) {
872 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
875 if (exp_y - exp_x > 19) {
876 // adjust the y significand upwards
877 __mul_128x128_to_256 (sig_n_prime256, sig_y,
878 __bid_ten2k128[exp_y - exp_x - 20]);
879 // if x and y represent the same entities and both are negative
880 // return true iff exp_x <= exp_y
881 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
882 && (sig_n_prime256.w[1] == sig_x.w[1])
883 && (sig_n_prime256.w[0] == sig_x.w[0])) {
884 res = (exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN);
887 // values are not equal, for positive numbers return 1 if x is less than y
889 res = (((sig_n_prime256.w[3] != 0) ||
890 // if upper128 bits of compensated y are non-zero, y is bigger
891 (sig_n_prime256.w[2] != 0) ||
892 // if upper128 bits of compensated y are non-zero, y is bigger
893 (sig_n_prime256.w[1] > sig_x.w[1]) ||
894 // if compensated y is bigger, y is bigger
895 (sig_n_prime256.w[1] == sig_x.w[1]
896 && sig_n_prime256.w[0] >
897 sig_x.w[0])) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
900 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[exp_y - exp_x], sig_y);
901 if ((sig_n_prime192.w[2] == 0) && (sig_n_prime192.w[1] == sig_x.w[1])
902 && (sig_n_prime192.w[0] == sig_x.w[0])) {
903 res = (exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN);
906 res = (((sig_n_prime192.w[2] != 0) ||
907 // if upper128 bits of compensated y are non-zero, y is bigger
908 (sig_n_prime192.w[1] > sig_x.w[1]) ||
909 // if compensated y is bigger, y is bigger
910 (sig_n_prime192.w[1] == sig_x.w[1]
911 && sig_n_prime192.w[0] >
912 sig_x.w[0])) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
916 #if DECIMAL_CALL_BY_REFERENCE
918 __bid128_totalOrderMag (int *pres, UINT128 * px,
919 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
924 __bid128_totalOrderMag (UINT128 x,
925 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
929 UINT128 sig_x, sig_y, pyld_y, pyld_x;
930 UINT192 sig_n_prime192;
931 UINT256 sig_n_prime256;
932 char x_is_zero = 0, y_is_zero = 0;
936 x.w[1] = x.w[1] & 0x7fffffffffffffffull;
937 y.w[1] = y.w[1] & 0x7fffffffffffffffull;
940 // if x and y are unordered numerically because either operand is NaN
941 // (1) totalOrder(number, +NaN) is true
942 // (2) if x and y are both NaN:
943 // i) signaling < quiet fir +NaN
944 // ii) lesser payload < greater payload for +NaN
945 if ((x.w[1] & MASK_NAN) == MASK_NAN) {
947 // return false, unless y is +NaN also
948 if ((y.w[1] & MASK_NAN) != MASK_NAN) {
949 res = 0; // y is a number, return 0
952 // x and y are both +NaN;
953 // must investigate payload if both quiet or both signaling
954 // this xnor statement will be true if both x and y are +QNaN or +SNaN
956 (((y.w[1] & MASK_SNAN) ==
957 MASK_SNAN) ^ ((x.w[1] & MASK_SNAN) == MASK_SNAN))) {
958 // it comes down to the payload. we want to return true if x has a
959 // smaller payload, but first we must calculate the payload.
960 pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull;
961 pyld_y.w[0] = y.w[0];
962 pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull;
963 pyld_x.w[0] = x.w[0];
964 // if x is zero and y isn't, x has the smaller payload definitely
965 // (since we know y isn't 0 at this point)
966 if ((pyld_x.w[1] > 0x0000314dc6448d93ull)
967 || ((pyld_x.w[1] == 0x0000314dc6448d93ull)
968 && (pyld_x.w[0] > 0x38c15b09ffffffffull))
969 || (pyld_x.w[1] == 0 && pyld_x.w[0] == 0)) {
973 if ((pyld_y.w[1] > 0x0000314dc6448d93ull)
974 || ((pyld_y.w[1] == 0x0000314dc6448d93ull)
975 && (pyld_y.w[0] > 0x38c15b09ffffffffull))
976 || (pyld_y.w[1] == 0 && pyld_y.w[0] == 0)) {
977 // if y is zero, x must be less than or numerically equal
981 res = ((pyld_x.w[1] < pyld_y.w[1])
982 || (pyld_x.w[1] == pyld_y.w[1]
983 && pyld_x.w[0] <= pyld_y.w[0]));
986 // return true if y is +QNaN and x is +SNaN
987 // (we know they're different bc of xor if_stmt above)
988 res = ((x.w[1] & MASK_SNAN) == MASK_SNAN);
992 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {
993 // x is certainly not NAN in this case.
994 // return true because y is positive
999 // if all the bits are the same, the numbers are equal.
1000 if ((x.w[1] == y.w[1]) && (x.w[0] == y.w[0])) {
1004 // INFINITY (CASE 3)
1005 if ((x.w[1] & MASK_INF) == MASK_INF) {
1006 // x is positive infinity, only return 1 if y is positive infinity as well
1007 res = ((y.w[1] & MASK_INF) == MASK_INF);
1009 // (we know y has same sign as x)
1010 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
1012 // since y is +inf, x<y
1020 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
1021 sig_x.w[0] = x.w[0];
1022 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
1024 // CHECK IF x IS CANONICAL
1025 // 9999999999999999999999999999999999 (decimal) =
1026 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1027 // [0, 10^34) is the 754r supported canonical range.
1028 // If the value exceeds that, it is interpreted as 0.
1029 if ((((sig_x.w[1] > 0x0001ed09bead87c0ull) ||
1030 ((sig_x.w[1] == 0x0001ed09bead87c0ull) &&
1031 (sig_x.w[0] > 0x378d8e63ffffffffull))) &&
1032 ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
1033 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
1034 ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1036 // check for the case where the exponent is shifted right by 2 bits!
1037 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
1038 exp_x = (x.w[1] >> 47) & 0x000000000003fffull;
1042 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
1043 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
1044 sig_y.w[0] = y.w[0];
1046 // CHECK IF y IS CANONICAL
1047 // 9999999999999999999999999999999999(decimal) =
1048 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1049 // [0, 10^34) is the 754r supported canonical range.
1050 // If the value exceeds that, it is interpreted as 0.
1051 if ((((sig_y.w[1] > 0x0001ed09bead87c0ull) ||
1052 ((sig_y.w[1] == 0x0001ed09bead87c0ull) &&
1053 (sig_y.w[0] > 0x378d8e63ffffffffull))) &&
1054 ((y.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
1055 ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
1056 ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1058 // check for the case where the exponent is shifted right by 2 bits!
1059 if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
1060 exp_y = (y.w[1] >> 47) & 0x000000000003fffull;
1064 if (x_is_zero && y_is_zero) {
1065 // we know that signs must be the same because we would have caught it
1066 // in case3 if signs were different
1067 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
1068 if (exp_x == exp_y) {
1072 res = (exp_x <= exp_y);
1075 // if x is zero and y isn't, clearly x has the smaller payload
1080 // if y is zero, and x isn't, clearly y has the smaller payload
1085 // REDUNDANT REPRESENTATIONS (CASE 5)
1086 // if both components are either bigger or smaller
1087 if (((sig_x.w[1] > sig_y.w[1])
1088 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
1089 && exp_x >= exp_y) {
1093 if (((sig_x.w[1] < sig_y.w[1])
1094 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
1095 && exp_x <= exp_y) {
1099 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1100 if (exp_x > exp_y) {
1101 // if exp_x is 33 greater than exp_y, it is definitely larger,
1102 // so no need for compensation
1103 if (exp_x - exp_y > 33) {
1104 res = 0; // difference cannot be greater than 10^33
1107 // otherwise adjust the x significand upwards
1108 if (exp_x - exp_y > 19) {
1109 __mul_128x128_to_256 (sig_n_prime256, sig_x,
1110 __bid_ten2k128[exp_x - exp_y - 20]);
1111 // the compensated significands are equal (ie "x and y represent the same
1112 // entities") return 1 if (negative && expx > expy) ||
1113 // (positive && expx < expy)
1114 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
1115 && (sig_n_prime256.w[1] == sig_y.w[1])
1116 && (sig_n_prime256.w[0] == sig_y.w[0])) {
1117 // the case (exp_x == exp_y) cannot occur, because all bits must be
1118 // the same - would have been caught if (x == y)
1119 res = (exp_x <= exp_y);
1122 // since positive, return 1 if adjusted x is smaller than y
1123 res = ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
1124 && ((sig_n_prime256.w[1] < sig_y.w[1])
1125 || (sig_n_prime256.w[1] == sig_y.w[1]
1126 && sig_n_prime256.w[0] < sig_y.w[0])));
1129 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[exp_x - exp_y], sig_x);
1130 // if positive, return whichever significand is larger
1131 // (converse if negative)
1132 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
1133 && (sig_n_prime192.w[0] == sig_y.w[0])) {
1134 res = (exp_x <= exp_y);
1137 res = ((sig_n_prime192.w[2] == 0)
1138 && ((sig_n_prime192.w[1] < sig_y.w[1])
1139 || (sig_n_prime192.w[1] == sig_y.w[1]
1140 && sig_n_prime192.w[0] < sig_y.w[0])));
1143 // if exp_x is 33 less than exp_y, it is definitely smaller,
1144 // no need for compensation
1145 if (exp_y - exp_x > 33) {
1149 if (exp_y - exp_x > 19) {
1150 // adjust the y significand upwards
1151 __mul_128x128_to_256 (sig_n_prime256, sig_y,
1152 __bid_ten2k128[exp_y - exp_x - 20]);
1153 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
1154 && (sig_n_prime256.w[1] == sig_x.w[1])
1155 && (sig_n_prime256.w[0] == sig_x.w[0])) {
1156 res = (exp_x <= exp_y);
1159 // values are not equal, for positive numbers return 1 if x is less than y
1161 res = ((sig_n_prime256.w[3] != 0) ||
1162 // if upper128 bits of compensated y are non-zero, y is bigger
1163 (sig_n_prime256.w[2] != 0) ||
1164 // if upper128 bits of compensated y are non-zero, y is bigger
1165 (sig_n_prime256.w[1] > sig_x.w[1]) ||
1166 // if compensated y is bigger, y is bigger
1167 (sig_n_prime256.w[1] == sig_x.w[1]
1168 && sig_n_prime256.w[0] > sig_x.w[0]));
1171 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[exp_y - exp_x], sig_y);
1172 if ((sig_n_prime192.w[2] == 0) && (sig_n_prime192.w[1] == sig_x.w[1])
1173 && (sig_n_prime192.w[0] == sig_x.w[0])) {
1174 res = (exp_x <= exp_y);
1177 res = ((sig_n_prime192.w[2] != 0) ||
1178 // if upper128 bits of compensated y are non-zero, y is bigger
1179 (sig_n_prime192.w[1] > sig_x.w[1]) ||
1180 // if compensated y is bigger, y is bigger
1181 (sig_n_prime192.w[1] == sig_x.w[1]
1182 && sig_n_prime192.w[0] > sig_x.w[0]));
1186 #if DECIMAL_CALL_BY_REFERENCE
1188 __bid128_radix (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
1192 __bid128_radix (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
1195 if (x.w[LOW_128W]) // dummy test