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
30 #include "bid_internal.h"
32 /*****************************************************************************
33 * BID128 minimum number
34 *****************************************************************************/
36 #if DECIMAL_CALL_BY_REFERENCE
38 __bid128_minnum (UINT128 * pres, UINT128 * px, UINT128 * py) {
43 __bid128_minnum (UINT128 x, UINT128 y) {
50 UINT192 sig_n_prime192;
51 UINT256 sig_n_prime256;
52 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
57 // if x is NAN, then return y
58 if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
59 if ((x.w[1] & 0x0200000000000000ull) == 0x0200000000000000ull) {
60 ; // *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN
62 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
64 ; // *pfpsf |= INVALID_EXCEPTION;
66 ; // y.w[1] = y.w[1] & 0xfdffffffffffffffull;
71 // if y is NAN, then return x
72 else if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
73 if ((y.w[1] & 0x0200000000000000ull) == 0x0200000000000000ull) {
74 ; // *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN
80 // if all the bits are the same, these numbers are equal (not Greater).
81 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
86 if ((x.w[1] & MASK_INF) == MASK_INF) {
87 // if x is neg infinity, there is no way it is greater than y, return 0
88 res = (((x.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
90 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
91 // x is finite, so if y is positive infinity, then x is less, return 0
92 // if y is negative infinity, then x is greater, return 1
93 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
97 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
99 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
101 // CHECK IF X IS CANONICAL
102 // 9999999999999999999999999999999999(decimal) =
103 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
104 // [0, 10^34) is the 754r supported canonical range.
105 // If the value exceeds that, it is interpreted as 0.
106 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
107 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
108 && (sig_x.w[0] > 0x378d8e63ffffffffull))
109 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
115 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
116 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
119 // CHECK IF Y IS CANONICAL
120 // 9999999999999999999999999999999999(decimal) =
121 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
122 // [0, 10^34) is the 754r supported canonical range.
123 // If the value exceeds that, it is interpreted as 0.
124 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
125 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
126 && (sig_y.w[0] > 0x378d8e63ffffffffull))
127 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
134 // (+ZERO == -ZERO) => therefore ignore the sign
135 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => ignore the exponent
137 // (Any non-canonical # is considered 0)
138 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
141 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
145 if (x_is_zero && y_is_zero) {
146 // if both numbers are zero, neither is greater => return either number
149 } else if (x_is_zero) {
150 // is x is zero, it is greater if Y is negative
151 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
153 } else if (y_is_zero) {
154 // is y is zero, X is greater if it is positive
155 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
158 // OPPOSITE SIGN (CASE5)
159 // now, if the sign bits differ, x is greater if y is negative
160 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
161 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
164 // REDUNDANT REPRESENTATIONS (CASE6)
165 // if exponents are the same, then we have a simple comparison of
167 if (exp_y == exp_x) {
168 res = (((sig_x.w[1] > sig_y.w[1])
169 || (sig_x.w[1] == sig_y.w[1]
170 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
174 // if both components are either bigger or smaller, it is clear what
176 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0]
178 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
181 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
183 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
187 diff = exp_x - exp_y;
189 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
190 if (diff > 0) { // to simplify the loop below,
191 // if exp_x is 33 greater than exp_y, no need for compensation
193 // difference cannot be greater than 10^33
194 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
197 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
198 __mul_128x128_to_256 (sig_n_prime256, sig_x, __bid_ten2k128[diff - 20]);
199 // if postitive, return whichever significand is larger
200 // (converse if negative)
201 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
202 || (sig_n_prime256.w[1] > sig_y.w[1])
203 || (sig_n_prime256.w[1] == sig_y.w[1]
204 && sig_n_prime256.w[0] >
205 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) ==
209 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[diff], sig_x);
210 // if postitive, return whichever significand is larger
211 // (converse if negative)
213 (((sig_n_prime192.w[2] > 0) || (sig_n_prime192.w[1] > sig_y.w[1])
214 || (sig_n_prime192.w[1] == sig_y.w[1]
215 && sig_n_prime192.w[0] >
216 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? y : x;
219 diff = exp_y - exp_x;
220 // if exp_x is 33 less than exp_y, no need for compensation
222 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
225 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
226 // adjust the y significand upwards
227 __mul_128x128_to_256 (sig_n_prime256, sig_y, __bid_ten2k128[diff - 20]);
228 // if postitive, return whichever significand is larger
229 // (converse if negative)
231 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
232 || (sig_n_prime256.w[1] > sig_x.w[1]
233 || (sig_n_prime256.w[1] == sig_x.w[1]
234 && sig_n_prime256.w[0] >
235 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
239 // adjust the y significand upwards
240 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[diff], sig_y);
241 // if postitive, return whichever significand is larger (converse if negative)
242 res = ((sig_n_prime192.w[2] != 0 || (sig_n_prime192.w[1] > sig_x.w[1] ||
243 (sig_n_prime192.w[1] == sig_x.w[1] && sig_n_prime192.w[0] > sig_x.w[0])))
244 ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
248 /*****************************************************************************
249 * BID128 minimum magnitude function - returns greater of two numbers
250 *****************************************************************************/
252 #if DECIMAL_CALL_BY_REFERENCE
254 __bid128_minnum_mag (UINT128 * pres, UINT128 * px, UINT128 * py) {
259 __bid128_minnum_mag (UINT128 x, UINT128 y) {
265 UINT128 sig_x, sig_y;
266 UINT192 sig_n_prime192;
267 UINT256 sig_n_prime256;
268 char non_canon_x, non_canon_y;
273 // if x is NAN, then return y
274 if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
275 if ((x.w[1] & 0x0200000000000000ull) == 0x0200000000000000ull) {
276 ; // *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN
278 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
280 ; // *pfpsf |= INVALID_EXCEPTION;
282 ; // y.w[1] = y.w[1] & 0xfdffffffffffffffull;
286 } else if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
287 // if y is NAN, then return x
288 if ((y.w[1] & 0x0200000000000000ull) == 0x0200000000000000ull) {
289 ; // *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN
295 // if all the bits are the same, these numbers are equal (not Greater).
296 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
301 if ((x.w[1] & MASK_INF) == MASK_INF) {
302 // if x infinity, it has maximum magnitude.
303 // Check if magnitudes are equal. If x is negative, return it.
304 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN
305 && (y.w[1] & MASK_INF) == MASK_INF) ? x : y;
307 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
308 // x is finite, so if y is infinity, then x is less in magnitude
313 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
315 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
317 // CHECK IF X IS CANONICAL
318 // 9999999999999999999999999999999999(decimal) =
319 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
320 // [0, 10^34) is the 754r supported canonical range.
321 // If the value exceeds that, it is interpreted as 0.
322 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
323 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
324 && (sig_x.w[0] > 0x378d8e63ffffffffull))
325 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
331 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
332 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
335 // CHECK IF Y IS CANONICAL
336 // 9999999999999999999999999999999999(decimal) =
337 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
338 // [0, 10^34) is the 754r supported canonical range.
339 // If the value exceeds that, it is interpreted as 0.
340 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
341 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
342 && (sig_y.w[0] > 0x378d8e63ffffffffull))
343 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
350 // (+ZERO == -ZERO) => therefore ignore the sign
351 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
352 // therefore ignore the exponent field
353 // (Any non-canonical # is considered 0)
354 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
358 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
362 // REDUNDANT REPRESENTATIONS (CASE6)
363 // check if exponents are the same and significands are the same
364 if (exp_y == exp_x && sig_x.w[1] == sig_y.w[1]
365 && sig_x.w[0] == sig_y.w[0]) {
366 if (x.w[1] & 0x8000000000000000ull) { // x is negative
373 } else if (((sig_x.w[1] > sig_y.w[1] || (sig_x.w[1] == sig_y.w[1]
374 && sig_x.w[0] > sig_y.w[0])) && exp_x == exp_y)
375 || ((sig_x.w[1] > sig_y.w[1]
376 || (sig_x.w[1] == sig_y.w[1]
377 && sig_x.w[0] >= sig_y.w[0]))
379 // if both components are either bigger or smaller, it is clear what
380 // needs to be done; also if the magnitudes are equal
383 } else if (((sig_y.w[1] > sig_x.w[1] || (sig_y.w[1] == sig_x.w[1]
384 && sig_y.w[0] > sig_x.w[0])) && exp_y == exp_x)
385 || ((sig_y.w[1] > sig_x.w[1]
386 || (sig_y.w[1] == sig_x.w[1]
387 && sig_y.w[0] >= sig_x.w[0]))
394 diff = exp_x - exp_y;
395 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
396 if (diff > 0) { // to simplify the loop below,
397 // if exp_x is 33 greater than exp_y, no need for compensation
399 res = y; // difference cannot be greater than 10^33
402 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
403 __mul_128x128_to_256 (sig_n_prime256, sig_x, __bid_ten2k128[diff - 20]);
404 // if positive, return whichever significand is larger
405 // (converse if negative)
406 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
407 && sig_n_prime256.w[1] == sig_y.w[1]
408 && (sig_n_prime256.w[0] == sig_y.w[0])) {
409 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x; // if equal
412 res = (((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
413 || (sig_n_prime256.w[1] > sig_y.w[1])
414 || (sig_n_prime256.w[1] == sig_y.w[1]
415 && sig_n_prime256.w[0] > sig_y.w[0])) ? y : x;
418 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[diff], sig_x);
419 // if positive, return whichever significand is larger
420 // (converse if negative)
421 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
422 && (sig_n_prime192.w[0] == sig_y.w[0])) {
423 // if = in magnitude, return +, (if possible)
424 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
427 res = ((sig_n_prime192.w[2] > 0)
428 || (sig_n_prime192.w[1] > sig_y.w[1])
429 || (sig_n_prime192.w[1] == sig_y.w[1]
430 && sig_n_prime192.w[0] > sig_y.w[0])) ? y : x;
433 diff = exp_y - exp_x;
434 // if exp_x is 33 less than exp_y, no need for compensation
439 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
440 // adjust the y significand upwards
441 __mul_128x128_to_256 (sig_n_prime256, sig_y, __bid_ten2k128[diff - 20]);
442 // if positive, return whichever significand is larger
443 // (converse if negative)
444 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
445 && sig_n_prime256.w[1] == sig_x.w[1]
446 && (sig_n_prime256.w[0] == sig_x.w[0])) {
447 // if = in magnitude, return +, (if possible)
448 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
451 res = (sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
452 && (sig_n_prime256.w[1] < sig_x.w[1]
453 || (sig_n_prime256.w[1] == sig_x.w[1]
454 && sig_n_prime256.w[0] < sig_x.w[0]))) ? y : x;
457 // adjust the y significand upwards
458 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[diff], sig_y);
459 // if positive, return whichever significand is larger (converse if negative)
460 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
461 && (sig_n_prime192.w[0] == sig_x.w[0])) {
462 // if = in magnitude, return +, if possible)
463 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
466 res = (sig_n_prime192.w[2] == 0 && (sig_n_prime192.w[1] < sig_x.w[1] ||
467 (sig_n_prime192.w[1] == sig_x.w[1] &&
468 sig_n_prime192.w[0] < sig_x.w[0]))) ? y : x;
472 /*****************************************************************************
473 * BID128 maximum function - returns greater of two numbers
474 *****************************************************************************/
476 #if DECIMAL_CALL_BY_REFERENCE
478 __bid128_maxnum (UINT128 * pres, UINT128 * px, UINT128 * py) {
483 __bid128_maxnum (UINT128 x, UINT128 y) {
489 UINT128 sig_x, sig_y;
490 UINT192 sig_n_prime192;
491 UINT256 sig_n_prime256;
492 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
497 if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
498 // if x is NAN, then return y
499 if ((x.w[1] & 0x0200000000000000ull) == 0x0200000000000000ull) {
500 ; // *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN
502 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
504 ; // *pfpsf |= INVALID_EXCEPTION;
506 ; // y.w[1] = y.w[1] & 0xfdffffffffffffffull;
510 } else if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
511 // if y is NAN, then return x
512 if ((y.w[1] & 0x0200000000000000ull) == 0x0200000000000000ull) {
513 ; // *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN
519 // if all the bits are the same, these numbers are equal (not Greater).
520 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
525 if ((x.w[1] & MASK_INF) == MASK_INF) {
526 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
528 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
529 // x is finite, so if y is positive infinity, then x is less, return 0
530 // if y is negative infinity, then x is greater, return 1
531 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
535 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
537 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
539 // CHECK IF X IS CANONICAL
540 // 9999999999999999999999999999999999(decimal) =
541 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
542 // [0, 10^34) is the 754r supported canonical range.
543 // If the value exceeds that, it is interpreted as 0.
544 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
545 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
546 && (sig_x.w[0] > 0x378d8e63ffffffffull))
547 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
553 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
554 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
557 // CHECK IF Y IS CANONICAL
558 // 9999999999999999999999999999999999(decimal) =
559 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
560 // [0, 10^34) is the 754r supported canonical range.
561 // If the value exceeds that, it is interpreted as 0.
562 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
563 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
564 && (sig_y.w[0] > 0x378d8e63ffffffffull))
565 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
572 // (+ZERO == -ZERO) => therefore ignore the sign
573 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
574 // therefore ignore the exponent field
575 // (Any non-canonical # is considered 0)
576 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
579 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
583 if (x_is_zero && y_is_zero) {
584 // if both numbers are zero, neither is greater => return either number
587 } else if (x_is_zero) {
588 // is x is zero, it is greater if Y is negative
589 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
591 } else if (y_is_zero) {
592 // is y is zero, X is greater if it is positive
593 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
596 // OPPOSITE SIGN (CASE5)
597 // now, if the sign bits differ, x is greater if y is negative
598 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
599 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
602 // REDUNDANT REPRESENTATIONS (CASE6)
603 // if exponents are the same, then we have a simple comparison of
605 if (exp_y == exp_x) {
606 res = (((sig_x.w[1] > sig_y.w[1]) || (sig_x.w[1] == sig_y.w[1] &&
607 sig_x.w[0] >= sig_y.w[0])) ^
608 ((x.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
611 // if both components are either bigger or smaller, it is clear what
613 if ((sig_x.w[1] > sig_y.w[1]
614 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
616 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
619 if ((sig_x.w[1] < sig_y.w[1]
620 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
622 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
625 diff = exp_x - exp_y;
626 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
627 if (diff > 0) { // to simplify the loop below,
628 // if exp_x is 33 greater than exp_y, no need for compensation
630 // difference cannot be greater than 10^33
631 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
634 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
635 __mul_128x128_to_256 (sig_n_prime256, sig_x, __bid_ten2k128[diff - 20]);
636 // if postitive, return whichever significand is larger
637 // (converse if negative)
638 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
639 || (sig_n_prime256.w[1] > sig_y.w[1])
640 || (sig_n_prime256.w[1] == sig_y.w[1]
641 && sig_n_prime256.w[0] >
642 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) ==
646 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[diff], sig_x);
647 // if postitive, return whichever significand is larger
648 // (converse if negative)
650 (((sig_n_prime192.w[2] > 0) || (sig_n_prime192.w[1] > sig_y.w[1])
651 || (sig_n_prime192.w[1] == sig_y.w[1]
652 && sig_n_prime192.w[0] >
653 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
656 diff = exp_y - exp_x;
657 // if exp_x is 33 less than exp_y, no need for compensation
659 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
662 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
663 // adjust the y significand upwards
664 __mul_128x128_to_256 (sig_n_prime256, sig_y, __bid_ten2k128[diff - 20]);
665 // if postitive, return whichever significand is larger
666 // (converse if negative)
668 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
669 || (sig_n_prime256.w[1] > sig_x.w[1]
670 || (sig_n_prime256.w[1] == sig_x.w[1]
671 && sig_n_prime256.w[0] >
672 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) !=
676 // adjust the y significand upwards
677 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[diff], sig_y);
678 // if postitive, return whichever significand is larger (converse if negative)
679 res = ((sig_n_prime192.w[2] != 0 || (sig_n_prime192.w[1] > sig_x.w[1] ||
680 (sig_n_prime192.w[1] == sig_x.w[1] &&
681 sig_n_prime192.w[0] > sig_x.w[0]))) ^
682 ((y.w[1] & MASK_SIGN) != MASK_SIGN)) ? x : y;
686 /*****************************************************************************
687 * BID128 maximum magnitude function - returns greater of two numbers
688 *****************************************************************************/
690 #if DECIMAL_CALL_BY_REFERENCE
692 __bid128_maxnum_mag (UINT128 * pres, UINT128 * px, UINT128 * py) {
697 __bid128_maxnum_mag (UINT128 x, UINT128 y) {
703 UINT128 sig_x, sig_y;
704 UINT192 sig_n_prime192;
705 UINT256 sig_n_prime256;
706 char non_canon_x, non_canon_y;
711 if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
712 // if x is NAN, then return y
713 if ((x.w[1] & 0x0200000000000000ull) == 0x0200000000000000ull) {
714 ; // *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN
716 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
718 ; // *pfpsf |= INVALID_EXCEPTION;
720 ; // y.w[1] = y.w[1] & 0xfdffffffffffffffull;
724 } else if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
725 // if y is NAN, then return x
726 if ((y.w[1] & 0x0200000000000000ull) == 0x0200000000000000ull) {
727 ; // *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN
733 // if all the bits are the same, these numbers are equal (not Greater).
734 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
739 if ((x.w[1] & MASK_INF) == MASK_INF) {
740 // if x infinity, it has maximum magnitude
741 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN
742 && (y.w[1] & MASK_INF) == MASK_INF) ? y : x;
744 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
745 // x is finite, so if y is positive infinity, then x is less, return 0
746 // if y is negative infinity, then x is greater, return 1
751 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
753 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
755 // CHECK IF X IS CANONICAL
756 // 9999999999999999999999999999999999(decimal) =
757 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
758 // [0, 10^34) is the 754r supported canonical range.
759 // If the value exceeds that, it is interpreted as 0.
760 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
761 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
762 && (sig_x.w[0] > 0x378d8e63ffffffffull))
763 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
769 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
770 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
773 // CHECK IF Y IS CANONICAL
774 // 9999999999999999999999999999999999(decimal) =
775 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
776 // [0, 10^34) is the 754r supported canonical range.
777 // If the value exceeds that, it is interpreted as 0.
778 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
779 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
780 && (sig_y.w[0] > 0x378d8e63ffffffffull))
781 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
788 // (+ZERO == -ZERO) => therefore ignore the sign
789 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
790 // therefore ignore the exponent field
791 // (Any non-canonical # is considered 0)
792 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
796 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
800 // REDUNDANT REPRESENTATIONS (CASE6)
801 if (exp_y == exp_x && sig_x.w[1] == sig_y.w[1]
802 && sig_x.w[0] == sig_y.w[0]) {
803 // check if exponents are the same and significands are the same
804 if (x.w[1] & 0x8000000000000000ull) { // x is negative
811 } else if (((sig_x.w[1] > sig_y.w[1] || (sig_x.w[1] == sig_y.w[1]
812 && sig_x.w[0] > sig_y.w[0])) && exp_x == exp_y)
813 || ((sig_x.w[1] > sig_y.w[1]
814 || (sig_x.w[1] == sig_y.w[1]
815 && sig_x.w[0] >= sig_y.w[0]))
817 // if both components are either bigger or smaller, it is clear what
818 // needs to be done; also if the magnitudes are equal
821 } else if (((sig_y.w[1] > sig_x.w[1] || (sig_y.w[1] == sig_x.w[1]
822 && sig_y.w[0] > sig_x.w[0])) && exp_y == exp_x)
823 || ((sig_y.w[1] > sig_x.w[1]
824 || (sig_y.w[1] == sig_x.w[1]
825 && sig_y.w[0] >= sig_x.w[0]))
832 diff = exp_x - exp_y;
833 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
834 if (diff > 0) { // to simplify the loop below,
835 // if exp_x is 33 greater than exp_y, no need for compensation
837 res = x; // difference cannot be greater than 10^33
840 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
841 __mul_128x128_to_256 (sig_n_prime256, sig_x, __bid_ten2k128[diff - 20]);
842 // if postitive, return whichever significand is larger
843 // (converse if negative)
844 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
845 && sig_n_prime256.w[1] == sig_y.w[1]
846 && (sig_n_prime256.w[0] == sig_y.w[0])) {
847 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y; // if equal
850 res = (((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
851 || (sig_n_prime256.w[1] > sig_y.w[1])
852 || (sig_n_prime256.w[1] == sig_y.w[1]
853 && sig_n_prime256.w[0] > sig_y.w[0])) ? x : y;
856 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[diff], sig_x);
857 // if postitive, return whichever significand is larger (converse if negative)
858 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
859 && (sig_n_prime192.w[0] == sig_y.w[0])) {
860 // if equal, return positive magnitude
861 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
864 res = ((sig_n_prime192.w[2] > 0)
865 || (sig_n_prime192.w[1] > sig_y.w[1])
866 || (sig_n_prime192.w[1] == sig_y.w[1]
867 && sig_n_prime192.w[0] > sig_y.w[0])) ? x : y;
870 diff = exp_y - exp_x;
871 // if exp_x is 33 less than exp_y, no need for compensation
876 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
877 // adjust the y significand upwards
878 __mul_128x128_to_256 (sig_n_prime256, sig_y, __bid_ten2k128[diff - 20]);
879 // if postitive, return whichever significand is larger
880 // (converse if negative)
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 // if equal, return positive (if possible)
885 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
888 res = (sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
889 && (sig_n_prime256.w[1] < sig_x.w[1]
890 || (sig_n_prime256.w[1] == sig_x.w[1]
891 && sig_n_prime256.w[0] < sig_x.w[0]))) ? x : y;
894 // adjust the y significand upwards
895 __mul_64x128_to_192 (sig_n_prime192, __bid_ten2k64[diff], sig_y);
896 // if postitive, return whichever significand is larger (converse if negative)
897 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
898 && (sig_n_prime192.w[0] == sig_x.w[0])) {
899 // if equal, return positive (if possible)
900 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
903 res = (sig_n_prime192.w[2] == 0 && (sig_n_prime192.w[1] < sig_x.w[1] ||
904 (sig_n_prime192.w[1] == sig_x.w[1] &&
905 sig_n_prime192.w[0] < sig_x.w[0]))) ? x : y;