1 /* Copyright (C) 2007, 2009 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
25 #include "bid_internal.h"
27 /*****************************************************************************
28 * BID128 minimum number
29 *****************************************************************************/
31 #if DECIMAL_CALL_BY_REFERENCE
33 bid128_minnum (UINT128
* pres
, UINT128
* px
,
34 UINT128
* py _EXC_FLAGS_PARAM
) {
39 bid128_minnum (UINT128 x
, UINT128 y _EXC_FLAGS_PARAM
) {
46 UINT192 sig_n_prime192
;
47 UINT256 sig_n_prime256
;
48 char x_is_zero
= 0, y_is_zero
= 0;
53 // check for non-canonical x
54 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
55 x
.w
[1] = x
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
56 // check for non-canonical NaN payload
57 if (((x
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
58 (((x
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
59 (x
.w
[0] > 0x38c15b09ffffffffull
))) {
60 x
.w
[1] = x
.w
[1] & 0xffffc00000000000ull
;
63 } else if ((x
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // x = inf
64 x
.w
[1] = x
.w
[1] & (MASK_SIGN
| MASK_INF
);
66 } else { // x is not special
67 // check for non-canonical values - treated as zero
68 if ((x
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
70 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | ((x
.w
[1] << 2) & MASK_EXP
);
72 } else { // G0_G1 != 11
73 if ((x
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
74 ((x
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
75 && x
.w
[0] > 0x378d8e63ffffffffull
)) {
76 // x is non-canonical if coefficient is larger than 10^34 -1
77 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | (x
.w
[1] & MASK_EXP
);
84 // check for non-canonical y
85 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
86 y
.w
[1] = y
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
87 // check for non-canonical NaN payload
88 if (((y
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
89 (((y
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
90 (y
.w
[0] > 0x38c15b09ffffffffull
))) {
91 y
.w
[1] = y
.w
[1] & 0xffffc00000000000ull
;
94 } else if ((y
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // y = inf
95 y
.w
[1] = y
.w
[1] & (MASK_SIGN
| MASK_INF
);
97 } else { // y is not special
98 // check for non-canonical values - treated as zero
99 if ((y
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
101 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | ((y
.w
[1] << 2) & MASK_EXP
);
103 } else { // G0_G1 != 11
104 if ((y
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
105 ((y
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
106 && y
.w
[0] > 0x378d8e63ffffffffull
)) {
107 // y is non-canonical if coefficient is larger than 10^34 -1
108 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | (y
.w
[1] & MASK_EXP
);
110 } else { // canonical
117 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
118 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
119 // if x is SNAN, then return quiet (x)
120 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
121 x
.w
[1] = x
.w
[1] & 0xfdffffffffffffffull
; // quietize x
123 } else { // x is QNaN
124 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
125 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
126 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
134 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
135 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) {
136 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
137 y
.w
[1] = y
.w
[1] & 0xfdffffffffffffffull
; // quietize y
140 // will return x (which is not NaN)
146 // if all the bits are the same, these numbers are equal (not Greater).
147 if (x
.w
[0] == y
.w
[0] && x
.w
[1] == y
.w
[1]) {
152 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
153 // if x is neg infinity, there is no way it is greater than y, return 0
154 res
= (((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
)) ? x
: y
;
156 } else if ((y
.w
[1] & MASK_INF
) == MASK_INF
) {
157 // x is finite, so if y is positive infinity, then x is less, return 0
158 // if y is negative infinity, then x is greater, return 1
159 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
163 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
165 exp_x
= (x
.w
[1] >> 49) & 0x000000000003fffull
;
168 exp_y
= (y
.w
[1] >> 49) & 0x0000000000003fffull
;
169 sig_y
.w
[1] = y
.w
[1] & 0x0001ffffffffffffull
;
174 // (+ZERO == -ZERO) => therefore ignore the sign
175 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => ignore the exponent
177 // (Any non-canonical # is considered 0)
178 if ((sig_x
.w
[1] == 0) && (sig_x
.w
[0] == 0)) {
181 if ((sig_y
.w
[1] == 0) && (sig_y
.w
[0] == 0)) {
185 if (x_is_zero
&& y_is_zero
) {
186 // if both numbers are zero, neither is greater => return either number
189 } else if (x_is_zero
) {
190 // is x is zero, it is greater if Y is negative
191 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
193 } else if (y_is_zero
) {
194 // is y is zero, X is greater if it is positive
195 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
) ? y
: x
;
198 // OPPOSITE SIGN (CASE5)
199 // now, if the sign bits differ, x is greater if y is negative
200 if (((x
.w
[1] ^ y
.w
[1]) & MASK_SIGN
) == MASK_SIGN
) {
201 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
204 // REDUNDANT REPRESENTATIONS (CASE6)
205 // if exponents are the same, then we have a simple comparison of
207 if (exp_y
== exp_x
) {
208 res
= (((sig_x
.w
[1] > sig_y
.w
[1])
209 || (sig_x
.w
[1] == sig_y
.w
[1]
210 && sig_x
.w
[0] >= sig_y
.w
[0])) ^ ((x
.w
[1] & MASK_SIGN
) ==
214 // if both components are either bigger or smaller, it is clear what
216 if (sig_x
.w
[1] >= sig_y
.w
[1] && sig_x
.w
[0] >= sig_y
.w
[0]
218 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
) ? y
: x
;
221 if (sig_x
.w
[1] <= sig_y
.w
[1] && sig_x
.w
[0] <= sig_y
.w
[0]
223 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
227 diff
= exp_x
- exp_y
;
229 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
230 if (diff
> 0) { // to simplify the loop below,
231 // if exp_x is 33 greater than exp_y, no need for compensation
233 // difference cannot be greater than 10^33
234 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
) ? y
: x
;
237 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
238 __mul_128x128_to_256 (sig_n_prime256
, sig_x
, ten2k128
[diff
- 20]);
239 // if postitive, return whichever significand is larger
240 // (converse if negative)
241 res
= ((((sig_n_prime256
.w
[3] > 0) || sig_n_prime256
.w
[2] > 0)
242 || (sig_n_prime256
.w
[1] > sig_y
.w
[1])
243 || (sig_n_prime256
.w
[1] == sig_y
.w
[1]
244 && sig_n_prime256
.w
[0] >
245 sig_y
.w
[0])) ^ ((y
.w
[1] & MASK_SIGN
) ==
249 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_x
);
250 // if postitive, return whichever significand is larger
251 // (converse if negative)
253 (((sig_n_prime192
.w
[2] > 0) || (sig_n_prime192
.w
[1] > sig_y
.w
[1])
254 || (sig_n_prime192
.w
[1] == sig_y
.w
[1]
255 && sig_n_prime192
.w
[0] >
256 sig_y
.w
[0])) ^ ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
)) ? y
: x
;
259 diff
= exp_y
- exp_x
;
260 // if exp_x is 33 less than exp_y, no need for compensation
262 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
265 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
266 // adjust the y significand upwards
267 __mul_128x128_to_256 (sig_n_prime256
, sig_y
, ten2k128
[diff
- 20]);
268 // if postitive, return whichever significand is larger
269 // (converse if negative)
271 ((sig_n_prime256
.w
[3] != 0 || sig_n_prime256
.w
[2] != 0
272 || (sig_n_prime256
.w
[1] > sig_x
.w
[1]
273 || (sig_n_prime256
.w
[1] == sig_x
.w
[1]
274 && sig_n_prime256
.w
[0] >
275 sig_x
.w
[0]))) ^ ((x
.w
[1] & MASK_SIGN
) ==
279 // adjust the y significand upwards
280 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_y
);
281 // if postitive, return whichever significand is larger (converse if negative)
283 ((sig_n_prime192
.w
[2] != 0
284 || (sig_n_prime192
.w
[1] > sig_x
.w
[1]
285 || (sig_n_prime192
.w
[1] == sig_x
.w
[1]
286 && sig_n_prime192
.w
[0] > sig_x
.w
[0])))
287 ^ ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
)) ? x
: y
;
291 /*****************************************************************************
292 * BID128 minimum magnitude function - returns greater of two numbers
293 *****************************************************************************/
295 #if DECIMAL_CALL_BY_REFERENCE
297 bid128_minnum_mag (UINT128
* pres
, UINT128
* px
,
298 UINT128
* py _EXC_FLAGS_PARAM
) {
303 bid128_minnum_mag (UINT128 x
, UINT128 y _EXC_FLAGS_PARAM
) {
309 UINT128 sig_x
, sig_y
;
310 UINT192 sig_n_prime192
;
311 UINT256 sig_n_prime256
;
316 // check for non-canonical x
317 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
318 x
.w
[1] = x
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
319 // check for non-canonical NaN payload
320 if (((x
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
321 (((x
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
322 (x
.w
[0] > 0x38c15b09ffffffffull
))) {
323 x
.w
[1] = x
.w
[1] & 0xffffc00000000000ull
;
326 } else if ((x
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // x = inf
327 x
.w
[1] = x
.w
[1] & (MASK_SIGN
| MASK_INF
);
329 } else { // x is not special
330 // check for non-canonical values - treated as zero
331 if ((x
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
333 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | ((x
.w
[1] << 2) & MASK_EXP
);
335 } else { // G0_G1 != 11
336 if ((x
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
337 ((x
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
338 && x
.w
[0] > 0x378d8e63ffffffffull
)) {
339 // x is non-canonical if coefficient is larger than 10^34 -1
340 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | (x
.w
[1] & MASK_EXP
);
342 } else { // canonical
347 // check for non-canonical y
348 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
349 y
.w
[1] = y
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
350 // check for non-canonical NaN payload
351 if (((y
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
352 (((y
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
353 (y
.w
[0] > 0x38c15b09ffffffffull
))) {
354 y
.w
[1] = y
.w
[1] & 0xffffc00000000000ull
;
357 } else if ((y
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // y = inf
358 y
.w
[1] = y
.w
[1] & (MASK_SIGN
| MASK_INF
);
360 } else { // y is not special
361 // check for non-canonical values - treated as zero
362 if ((y
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
364 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | ((y
.w
[1] << 2) & MASK_EXP
);
366 } else { // G0_G1 != 11
367 if ((y
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
368 ((y
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
369 && y
.w
[0] > 0x378d8e63ffffffffull
)) {
370 // y is non-canonical if coefficient is larger than 10^34 -1
371 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | (y
.w
[1] & MASK_EXP
);
373 } else { // canonical
380 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
381 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
382 // if x is SNAN, then return quiet (x)
383 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
384 x
.w
[1] = x
.w
[1] & 0xfdffffffffffffffull
; // quietize x
386 } else { // x is QNaN
387 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
388 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
389 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
397 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
398 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) {
399 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
400 y
.w
[1] = y
.w
[1] & 0xfdffffffffffffffull
; // quietize y
403 // will return x (which is not NaN)
409 // if all the bits are the same, these numbers are equal (not Greater).
410 if (x
.w
[0] == y
.w
[0] && x
.w
[1] == y
.w
[1]) {
415 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
416 // if x infinity, it has maximum magnitude.
417 // Check if magnitudes are equal. If x is negative, return it.
418 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
419 && (y
.w
[1] & MASK_INF
) == MASK_INF
) ? x
: y
;
421 } else if ((y
.w
[1] & MASK_INF
) == MASK_INF
) {
422 // x is finite, so if y is infinity, then x is less in magnitude
427 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
429 exp_x
= (x
.w
[1] >> 49) & 0x000000000003fffull
;
432 exp_y
= (y
.w
[1] >> 49) & 0x0000000000003fffull
;
433 sig_y
.w
[1] = y
.w
[1] & 0x0001ffffffffffffull
;
438 // (+ZERO == -ZERO) => therefore ignore the sign
439 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
440 // therefore ignore the exponent field
441 // (Any non-canonical # is considered 0)
442 if ((sig_x
.w
[1] == 0) && (sig_x
.w
[0] == 0)) {
446 if ((sig_y
.w
[1] == 0) && (sig_y
.w
[0] == 0)) {
450 // REDUNDANT REPRESENTATIONS (CASE6)
451 // check if exponents are the same and significands are the same
452 if (exp_y
== exp_x
&& sig_x
.w
[1] == sig_y
.w
[1]
453 && sig_x
.w
[0] == sig_y
.w
[0]) {
454 if (x
.w
[1] & 0x8000000000000000ull
) { // x is negative
461 } else if (((sig_x
.w
[1] > sig_y
.w
[1] || (sig_x
.w
[1] == sig_y
.w
[1]
462 && sig_x
.w
[0] > sig_y
.w
[0]))
464 || ((sig_x
.w
[1] > sig_y
.w
[1]
465 || (sig_x
.w
[1] == sig_y
.w
[1]
466 && sig_x
.w
[0] >= sig_y
.w
[0]))
468 // if both components are either bigger or smaller, it is clear what
469 // needs to be done; also if the magnitudes are equal
472 } else if (((sig_y
.w
[1] > sig_x
.w
[1] || (sig_y
.w
[1] == sig_x
.w
[1]
473 && sig_y
.w
[0] > sig_x
.w
[0]))
475 || ((sig_y
.w
[1] > sig_x
.w
[1]
476 || (sig_y
.w
[1] == sig_x
.w
[1]
477 && sig_y
.w
[0] >= sig_x
.w
[0]))
484 diff
= exp_x
- exp_y
;
485 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
486 if (diff
> 0) { // to simplify the loop below,
487 // if exp_x is 33 greater than exp_y, no need for compensation
489 res
= y
; // difference cannot be greater than 10^33
492 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
493 __mul_128x128_to_256 (sig_n_prime256
, sig_x
, ten2k128
[diff
- 20]);
494 // if positive, return whichever significand is larger
495 // (converse if negative)
496 if (sig_n_prime256
.w
[3] == 0 && (sig_n_prime256
.w
[2] == 0)
497 && sig_n_prime256
.w
[1] == sig_y
.w
[1]
498 && (sig_n_prime256
.w
[0] == sig_y
.w
[0])) {
499 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
; // if equal
502 res
= (((sig_n_prime256
.w
[3] > 0) || sig_n_prime256
.w
[2] > 0)
503 || (sig_n_prime256
.w
[1] > sig_y
.w
[1])
504 || (sig_n_prime256
.w
[1] == sig_y
.w
[1]
505 && sig_n_prime256
.w
[0] > sig_y
.w
[0])) ? y
: x
;
508 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_x
);
509 // if positive, return whichever significand is larger
510 // (converse if negative)
511 if ((sig_n_prime192
.w
[2] == 0) && sig_n_prime192
.w
[1] == sig_y
.w
[1]
512 && (sig_n_prime192
.w
[0] == sig_y
.w
[0])) {
513 // if = in magnitude, return +, (if possible)
514 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
517 res
= ((sig_n_prime192
.w
[2] > 0)
518 || (sig_n_prime192
.w
[1] > sig_y
.w
[1])
519 || (sig_n_prime192
.w
[1] == sig_y
.w
[1]
520 && sig_n_prime192
.w
[0] > sig_y
.w
[0])) ? y
: x
;
523 diff
= exp_y
- exp_x
;
524 // if exp_x is 33 less than exp_y, no need for compensation
529 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
530 // adjust the y significand upwards
531 __mul_128x128_to_256 (sig_n_prime256
, sig_y
, ten2k128
[diff
- 20]);
532 // if positive, return whichever significand is larger
533 // (converse if negative)
534 if (sig_n_prime256
.w
[3] == 0 && (sig_n_prime256
.w
[2] == 0)
535 && sig_n_prime256
.w
[1] == sig_x
.w
[1]
536 && (sig_n_prime256
.w
[0] == sig_x
.w
[0])) {
537 // if = in magnitude, return +, (if possible)
538 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
541 res
= (sig_n_prime256
.w
[3] == 0 && sig_n_prime256
.w
[2] == 0
542 && (sig_n_prime256
.w
[1] < sig_x
.w
[1]
543 || (sig_n_prime256
.w
[1] == sig_x
.w
[1]
544 && sig_n_prime256
.w
[0] < sig_x
.w
[0]))) ? y
: x
;
547 // adjust the y significand upwards
548 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_y
);
549 // if positive, return whichever significand is larger (converse if negative)
550 if ((sig_n_prime192
.w
[2] == 0) && sig_n_prime192
.w
[1] == sig_x
.w
[1]
551 && (sig_n_prime192
.w
[0] == sig_x
.w
[0])) {
552 // if = in magnitude, return +, if possible)
553 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
556 res
= (sig_n_prime192
.w
[2] == 0
557 && (sig_n_prime192
.w
[1] < sig_x
.w
[1]
558 || (sig_n_prime192
.w
[1] == sig_x
.w
[1]
559 && sig_n_prime192
.w
[0] < sig_x
.w
[0]))) ? y
: x
;
563 /*****************************************************************************
564 * BID128 maximum function - returns greater of two numbers
565 *****************************************************************************/
567 #if DECIMAL_CALL_BY_REFERENCE
569 bid128_maxnum (UINT128
* pres
, UINT128
* px
,
570 UINT128
* py _EXC_FLAGS_PARAM
) {
575 bid128_maxnum (UINT128 x
, UINT128 y _EXC_FLAGS_PARAM
) {
581 UINT128 sig_x
, sig_y
;
582 UINT192 sig_n_prime192
;
583 UINT256 sig_n_prime256
;
584 char x_is_zero
= 0, y_is_zero
= 0;
589 // check for non-canonical x
590 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
591 x
.w
[1] = x
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
592 // check for non-canonical NaN payload
593 if (((x
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
594 (((x
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
595 (x
.w
[0] > 0x38c15b09ffffffffull
))) {
596 x
.w
[1] = x
.w
[1] & 0xffffc00000000000ull
;
599 } else if ((x
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // x = inf
600 x
.w
[1] = x
.w
[1] & (MASK_SIGN
| MASK_INF
);
602 } else { // x is not special
603 // check for non-canonical values - treated as zero
604 if ((x
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
606 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | ((x
.w
[1] << 2) & MASK_EXP
);
608 } else { // G0_G1 != 11
609 if ((x
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
610 ((x
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
611 && x
.w
[0] > 0x378d8e63ffffffffull
)) {
612 // x is non-canonical if coefficient is larger than 10^34 -1
613 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | (x
.w
[1] & MASK_EXP
);
615 } else { // canonical
620 // check for non-canonical y
621 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
622 y
.w
[1] = y
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
623 // check for non-canonical NaN payload
624 if (((y
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
625 (((y
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
626 (y
.w
[0] > 0x38c15b09ffffffffull
))) {
627 y
.w
[1] = y
.w
[1] & 0xffffc00000000000ull
;
630 } else if ((y
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // y = inf
631 y
.w
[1] = y
.w
[1] & (MASK_SIGN
| MASK_INF
);
633 } else { // y is not special
634 // check for non-canonical values - treated as zero
635 if ((y
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
637 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | ((y
.w
[1] << 2) & MASK_EXP
);
639 } else { // G0_G1 != 11
640 if ((y
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
641 ((y
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
642 && y
.w
[0] > 0x378d8e63ffffffffull
)) {
643 // y is non-canonical if coefficient is larger than 10^34 -1
644 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | (y
.w
[1] & MASK_EXP
);
646 } else { // canonical
653 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
654 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
655 // if x is SNAN, then return quiet (x)
656 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
657 x
.w
[1] = x
.w
[1] & 0xfdffffffffffffffull
; // quietize x
659 } else { // x is QNaN
660 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
661 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
662 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
670 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
671 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) {
672 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
673 y
.w
[1] = y
.w
[1] & 0xfdffffffffffffffull
; // quietize y
676 // will return x (which is not NaN)
682 // if all the bits are the same, these numbers are equal (not Greater).
683 if (x
.w
[0] == y
.w
[0] && x
.w
[1] == y
.w
[1]) {
688 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
689 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
691 } else if ((y
.w
[1] & MASK_INF
) == MASK_INF
) {
692 // x is finite, so if y is positive infinity, then x is less, return 0
693 // if y is negative infinity, then x is greater, return 1
694 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
698 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
700 exp_x
= (x
.w
[1] >> 49) & 0x000000000003fffull
;
703 exp_y
= (y
.w
[1] >> 49) & 0x0000000000003fffull
;
704 sig_y
.w
[1] = y
.w
[1] & 0x0001ffffffffffffull
;
709 // (+ZERO == -ZERO) => therefore ignore the sign
710 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
711 // therefore ignore the exponent field
712 // (Any non-canonical # is considered 0)
713 if ((sig_x
.w
[1] == 0) && (sig_x
.w
[0] == 0)) {
716 if ((sig_y
.w
[1] == 0) && (sig_y
.w
[0] == 0)) {
720 if (x_is_zero
&& y_is_zero
) {
721 // if both numbers are zero, neither is greater => return either number
724 } else if (x_is_zero
) {
725 // is x is zero, it is greater if Y is negative
726 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
728 } else if (y_is_zero
) {
729 // is y is zero, X is greater if it is positive
730 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
) ? x
: y
;
733 // OPPOSITE SIGN (CASE5)
734 // now, if the sign bits differ, x is greater if y is negative
735 if (((x
.w
[1] ^ y
.w
[1]) & MASK_SIGN
) == MASK_SIGN
) {
736 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
739 // REDUNDANT REPRESENTATIONS (CASE6)
740 // if exponents are the same, then we have a simple comparison of
742 if (exp_y
== exp_x
) {
743 res
= (((sig_x
.w
[1] > sig_y
.w
[1]) || (sig_x
.w
[1] == sig_y
.w
[1] &&
744 sig_x
.w
[0] >= sig_y
.w
[0])) ^
745 ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
)) ? x
: y
;
748 // if both components are either bigger or smaller, it is clear what
750 if ((sig_x
.w
[1] > sig_y
.w
[1]
751 || (sig_x
.w
[1] == sig_y
.w
[1] && sig_x
.w
[0] > sig_y
.w
[0]))
753 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
) ? x
: y
;
756 if ((sig_x
.w
[1] < sig_y
.w
[1]
757 || (sig_x
.w
[1] == sig_y
.w
[1] && sig_x
.w
[0] < sig_y
.w
[0]))
759 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
762 diff
= exp_x
- exp_y
;
763 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
764 if (diff
> 0) { // to simplify the loop below,
765 // if exp_x is 33 greater than exp_y, no need for compensation
767 // difference cannot be greater than 10^33
768 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
) ? x
: y
;
771 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
772 __mul_128x128_to_256 (sig_n_prime256
, sig_x
, ten2k128
[diff
- 20]);
773 // if postitive, return whichever significand is larger
774 // (converse if negative)
775 res
= ((((sig_n_prime256
.w
[3] > 0) || sig_n_prime256
.w
[2] > 0)
776 || (sig_n_prime256
.w
[1] > sig_y
.w
[1])
777 || (sig_n_prime256
.w
[1] == sig_y
.w
[1]
778 && sig_n_prime256
.w
[0] >
779 sig_y
.w
[0])) ^ ((y
.w
[1] & MASK_SIGN
) ==
783 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_x
);
784 // if postitive, return whichever significand is larger
785 // (converse if negative)
787 (((sig_n_prime192
.w
[2] > 0) || (sig_n_prime192
.w
[1] > sig_y
.w
[1])
788 || (sig_n_prime192
.w
[1] == sig_y
.w
[1]
789 && sig_n_prime192
.w
[0] >
790 sig_y
.w
[0])) ^ ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
)) ? x
: y
;
793 diff
= exp_y
- exp_x
;
794 // if exp_x is 33 less than exp_y, no need for compensation
796 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
799 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
800 // adjust the y significand upwards
801 __mul_128x128_to_256 (sig_n_prime256
, sig_y
, ten2k128
[diff
- 20]);
802 // if postitive, return whichever significand is larger
803 // (converse if negative)
805 ((sig_n_prime256
.w
[3] != 0 || sig_n_prime256
.w
[2] != 0
806 || (sig_n_prime256
.w
[1] > sig_x
.w
[1]
807 || (sig_n_prime256
.w
[1] == sig_x
.w
[1]
808 && sig_n_prime256
.w
[0] >
809 sig_x
.w
[0]))) ^ ((x
.w
[1] & MASK_SIGN
) !=
813 // adjust the y significand upwards
814 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_y
);
815 // if postitive, return whichever significand is larger (converse if negative)
817 ((sig_n_prime192
.w
[2] != 0
818 || (sig_n_prime192
.w
[1] > sig_x
.w
[1]
819 || (sig_n_prime192
.w
[1] == sig_x
.w
[1]
820 && sig_n_prime192
.w
[0] >
821 sig_x
.w
[0]))) ^ ((y
.w
[1] & MASK_SIGN
) !=
826 /*****************************************************************************
827 * BID128 maximum magnitude function - returns greater of two numbers
828 *****************************************************************************/
830 #if DECIMAL_CALL_BY_REFERENCE
832 bid128_maxnum_mag (UINT128
* pres
, UINT128
* px
,
833 UINT128
* py _EXC_FLAGS_PARAM
) {
838 bid128_maxnum_mag (UINT128 x
, UINT128 y _EXC_FLAGS_PARAM
) {
844 UINT128 sig_x
, sig_y
;
845 UINT192 sig_n_prime192
;
846 UINT256 sig_n_prime256
;
851 // check for non-canonical x
852 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
853 x
.w
[1] = x
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
854 // check for non-canonical NaN payload
855 if (((x
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
856 (((x
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
857 (x
.w
[0] > 0x38c15b09ffffffffull
))) {
858 x
.w
[1] = x
.w
[1] & 0xffffc00000000000ull
;
861 } else if ((x
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // x = inf
862 x
.w
[1] = x
.w
[1] & (MASK_SIGN
| MASK_INF
);
864 } else { // x is not special
865 // check for non-canonical values - treated as zero
866 if ((x
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
868 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | ((x
.w
[1] << 2) & MASK_EXP
);
870 } else { // G0_G1 != 11
871 if ((x
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
872 ((x
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
873 && x
.w
[0] > 0x378d8e63ffffffffull
)) {
874 // x is non-canonical if coefficient is larger than 10^34 -1
875 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | (x
.w
[1] & MASK_EXP
);
877 } else { // canonical
882 // check for non-canonical y
883 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
884 y
.w
[1] = y
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
885 // check for non-canonical NaN payload
886 if (((y
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
887 (((y
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
888 (y
.w
[0] > 0x38c15b09ffffffffull
))) {
889 y
.w
[1] = y
.w
[1] & 0xffffc00000000000ull
;
892 } else if ((y
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // y = inf
893 y
.w
[1] = y
.w
[1] & (MASK_SIGN
| MASK_INF
);
895 } else { // y is not special
896 // check for non-canonical values - treated as zero
897 if ((y
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
899 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | ((y
.w
[1] << 2) & MASK_EXP
);
901 } else { // G0_G1 != 11
902 if ((y
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
903 ((y
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
&&
904 y
.w
[0] > 0x378d8e63ffffffffull
)) {
905 // y is non-canonical if coefficient is larger than 10^34 -1
906 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | (y
.w
[1] & MASK_EXP
);
908 } else { // canonical
915 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
916 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
917 // if x is SNAN, then return quiet (x)
918 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
919 x
.w
[1] = x
.w
[1] & 0xfdffffffffffffffull
; // quietize x
921 } else { // x is QNaN
922 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
923 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
924 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
932 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
933 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) {
934 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
935 y
.w
[1] = y
.w
[1] & 0xfdffffffffffffffull
; // quietize y
938 // will return x (which is not NaN)
944 // if all the bits are the same, these numbers are equal (not Greater).
945 if (x
.w
[0] == y
.w
[0] && x
.w
[1] == y
.w
[1]) {
950 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
951 // if x infinity, it has maximum magnitude
952 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
953 && (y
.w
[1] & MASK_INF
) == MASK_INF
) ? y
: x
;
955 } else if ((y
.w
[1] & MASK_INF
) == MASK_INF
) {
956 // x is finite, so if y is positive infinity, then x is less, return 0
957 // if y is negative infinity, then x is greater, return 1
962 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
964 exp_x
= (x
.w
[1] >> 49) & 0x000000000003fffull
;
967 exp_y
= (y
.w
[1] >> 49) & 0x0000000000003fffull
;
968 sig_y
.w
[1] = y
.w
[1] & 0x0001ffffffffffffull
;
973 // (+ZERO == -ZERO) => therefore ignore the sign
974 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
975 // therefore ignore the exponent field
976 // (Any non-canonical # is considered 0)
977 if ((sig_x
.w
[1] == 0) && (sig_x
.w
[0] == 0)) {
981 if ((sig_y
.w
[1] == 0) && (sig_y
.w
[0] == 0)) {
985 // REDUNDANT REPRESENTATIONS (CASE6)
986 if (exp_y
== exp_x
&& sig_x
.w
[1] == sig_y
.w
[1]
987 && sig_x
.w
[0] == sig_y
.w
[0]) {
988 // check if exponents are the same and significands are the same
989 if (x
.w
[1] & 0x8000000000000000ull
) { // x is negative
996 } else if (((sig_x
.w
[1] > sig_y
.w
[1] || (sig_x
.w
[1] == sig_y
.w
[1]
997 && sig_x
.w
[0] > sig_y
.w
[0]))
999 || ((sig_x
.w
[1] > sig_y
.w
[1]
1000 || (sig_x
.w
[1] == sig_y
.w
[1]
1001 && sig_x
.w
[0] >= sig_y
.w
[0]))
1002 && exp_x
> exp_y
)) {
1003 // if both components are either bigger or smaller, it is clear what
1004 // needs to be done; also if the magnitudes are equal
1007 } else if (((sig_y
.w
[1] > sig_x
.w
[1] || (sig_y
.w
[1] == sig_x
.w
[1]
1008 && sig_y
.w
[0] > sig_x
.w
[0]))
1010 || ((sig_y
.w
[1] > sig_x
.w
[1]
1011 || (sig_y
.w
[1] == sig_x
.w
[1]
1012 && sig_y
.w
[0] >= sig_x
.w
[0]))
1013 && exp_y
> exp_x
)) {
1019 diff
= exp_x
- exp_y
;
1020 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1021 if (diff
> 0) { // to simplify the loop below,
1022 // if exp_x is 33 greater than exp_y, no need for compensation
1024 res
= x
; // difference cannot be greater than 10^33
1027 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
1028 __mul_128x128_to_256 (sig_n_prime256
, sig_x
, ten2k128
[diff
- 20]);
1029 // if postitive, return whichever significand is larger
1030 // (converse if negative)
1031 if (sig_n_prime256
.w
[3] == 0 && (sig_n_prime256
.w
[2] == 0)
1032 && sig_n_prime256
.w
[1] == sig_y
.w
[1]
1033 && (sig_n_prime256
.w
[0] == sig_y
.w
[0])) {
1034 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
; // if equal
1037 res
= (((sig_n_prime256
.w
[3] > 0) || sig_n_prime256
.w
[2] > 0)
1038 || (sig_n_prime256
.w
[1] > sig_y
.w
[1])
1039 || (sig_n_prime256
.w
[1] == sig_y
.w
[1]
1040 && sig_n_prime256
.w
[0] > sig_y
.w
[0])) ? x
: y
;
1043 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_x
);
1044 // if postitive, return whichever significand is larger (converse if negative)
1045 if ((sig_n_prime192
.w
[2] == 0) && sig_n_prime192
.w
[1] == sig_y
.w
[1]
1046 && (sig_n_prime192
.w
[0] == sig_y
.w
[0])) {
1047 // if equal, return positive magnitude
1048 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
1051 res
= ((sig_n_prime192
.w
[2] > 0)
1052 || (sig_n_prime192
.w
[1] > sig_y
.w
[1])
1053 || (sig_n_prime192
.w
[1] == sig_y
.w
[1]
1054 && sig_n_prime192
.w
[0] > sig_y
.w
[0])) ? x
: y
;
1057 diff
= exp_y
- exp_x
;
1058 // if exp_x is 33 less than exp_y, no need for compensation
1063 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
1064 // adjust the y significand upwards
1065 __mul_128x128_to_256 (sig_n_prime256
, sig_y
, ten2k128
[diff
- 20]);
1066 // if postitive, return whichever significand is larger
1067 // (converse if negative)
1068 if (sig_n_prime256
.w
[3] == 0 && (sig_n_prime256
.w
[2] == 0)
1069 && sig_n_prime256
.w
[1] == sig_x
.w
[1]
1070 && (sig_n_prime256
.w
[0] == sig_x
.w
[0])) {
1071 // if equal, return positive (if possible)
1072 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
1075 res
= (sig_n_prime256
.w
[3] == 0 && sig_n_prime256
.w
[2] == 0
1076 && (sig_n_prime256
.w
[1] < sig_x
.w
[1]
1077 || (sig_n_prime256
.w
[1] == sig_x
.w
[1]
1078 && sig_n_prime256
.w
[0] < sig_x
.w
[0]))) ? x
: y
;
1081 // adjust the y significand upwards
1082 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_y
);
1083 // if postitive, return whichever significand is larger (converse if negative)
1084 if ((sig_n_prime192
.w
[2] == 0) && sig_n_prime192
.w
[1] == sig_x
.w
[1]
1085 && (sig_n_prime192
.w
[0] == sig_x
.w
[0])) {
1086 // if equal, return positive (if possible)
1087 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
1090 res
= (sig_n_prime192
.w
[2] == 0
1091 && (sig_n_prime192
.w
[1] < sig_x
.w
[1]
1092 || (sig_n_prime192
.w
[1] == sig_x
.w
[1]
1093 && sig_n_prime192
.w
[0] < sig_x
.w
[0]))) ? x
: y
;