1 /* Copyright (C) 2007-2024 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
24 #include "bid_internal.h"
26 /*****************************************************************************
27 * BID64 minimum function - returns greater of two numbers
28 *****************************************************************************/
30 static const UINT64 mult_factor
[16] = {
31 1ull, 10ull, 100ull, 1000ull,
32 10000ull, 100000ull, 1000000ull, 10000000ull,
33 100000000ull, 1000000000ull, 10000000000ull, 100000000000ull,
34 1000000000000ull, 10000000000000ull,
35 100000000000000ull, 1000000000000000ull
38 #if DECIMAL_CALL_BY_REFERENCE
40 bid64_minnum (UINT64
* pres
, UINT64
* px
, UINT64
* py _EXC_FLAGS_PARAM
) {
45 bid64_minnum (UINT64 x
, UINT64 y _EXC_FLAGS_PARAM
) {
52 char x_is_zero
= 0, y_is_zero
= 0;
54 // check for non-canonical x
55 if ((x
& MASK_NAN
) == MASK_NAN
) { // x is NaN
56 x
= x
& 0xfe03ffffffffffffull
; // clear G6-G12
57 if ((x
& 0x0003ffffffffffffull
) > 999999999999999ull) {
58 x
= x
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
60 } else if ((x
& MASK_INF
) == MASK_INF
) { // check for Infinity
61 x
= x
& (MASK_SIGN
| MASK_INF
);
62 } else { // x is not special
63 // check for non-canonical values - treated as zero
64 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
65 // if the steering bits are 11, then the exponent is G[0:w+1]
66 if (((x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
) >
67 9999999999999999ull) {
69 x
= (x
& MASK_SIGN
) | ((x
& MASK_BINARY_EXPONENT2
) << 2);
74 // check for non-canonical y
75 if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NaN
76 y
= y
& 0xfe03ffffffffffffull
; // clear G6-G12
77 if ((y
& 0x0003ffffffffffffull
) > 999999999999999ull) {
78 y
= y
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
80 } else if ((y
& MASK_INF
) == MASK_INF
) { // check for Infinity
81 y
= y
& (MASK_SIGN
| MASK_INF
);
82 } else { // y is not special
83 // check for non-canonical values - treated as zero
84 if ((y
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
85 // if the steering bits are 11, then the exponent is G[0:w+1]
86 if (((y
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
) >
87 9999999999999999ull) {
89 y
= (y
& MASK_SIGN
) | ((y
& MASK_BINARY_EXPONENT2
) << 2);
95 if ((x
& MASK_NAN
) == MASK_NAN
) { // x is NAN
96 if ((x
& MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
97 // if x is SNAN, then return quiet (x)
98 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
99 x
= x
& 0xfdffffffffffffffull
; // quietize x
101 } else { // x is QNaN
102 if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NAN
103 if ((y
& MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
104 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
112 } else if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
113 if ((y
& MASK_SNAN
) == MASK_SNAN
) {
114 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
115 y
= y
& 0xfdffffffffffffffull
; // quietize y
118 // will return x (which is not NaN)
124 // if all the bits are the same, these numbers are equal, return either number
130 if ((x
& MASK_INF
) == MASK_INF
) {
131 // if x is neg infinity, there is no way it is greater than y, return x
132 if (((x
& MASK_SIGN
) == MASK_SIGN
)) {
136 // x is pos infinity, return y
141 } else if ((y
& MASK_INF
) == MASK_INF
) {
142 // x is finite, so if y is positive infinity, then x is less, return y
143 // if y is negative infinity, then x is greater, return x
144 res
= ((y
& MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
147 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
148 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
149 exp_x
= (x
& MASK_BINARY_EXPONENT2
) >> 51;
150 sig_x
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
152 exp_x
= (x
& MASK_BINARY_EXPONENT1
) >> 53;
153 sig_x
= (x
& MASK_BINARY_SIG1
);
156 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
157 if ((y
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
158 exp_y
= (y
& MASK_BINARY_EXPONENT2
) >> 51;
159 sig_y
= (y
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
161 exp_y
= (y
& MASK_BINARY_EXPONENT1
) >> 53;
162 sig_y
= (y
& MASK_BINARY_SIG1
);
167 // (+ZERO == -ZERO) => therefore
168 // ignore the sign, and neither number is greater
169 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
170 // ignore the exponent field
171 // (Any non-canonical # is considered 0)
179 if (x_is_zero
&& y_is_zero
) {
180 // if both numbers are zero, neither is greater => return either
183 } else if (x_is_zero
) {
184 // is x is zero, it is greater if Y is negative
185 res
= ((y
& MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
187 } else if (y_is_zero
) {
188 // is y is zero, X is greater if it is positive
189 res
= ((x
& MASK_SIGN
) != MASK_SIGN
) ? y
: x
;;
192 // OPPOSITE SIGN (CASE5)
193 // now, if the sign bits differ, x is greater if y is negative
194 if (((x
^ y
) & MASK_SIGN
) == MASK_SIGN
) {
195 res
= ((y
& MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
198 // REDUNDANT REPRESENTATIONS (CASE6)
200 // if both components are either bigger or smaller,
201 // it is clear what needs to be done
202 if (sig_x
> sig_y
&& exp_x
>= exp_y
) {
203 res
= ((x
& MASK_SIGN
) != MASK_SIGN
) ? y
: x
;
206 if (sig_x
< sig_y
&& exp_x
<= exp_y
) {
207 res
= ((x
& MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
210 // if exp_x is 15 greater than exp_y, no need for compensation
211 if (exp_x
- exp_y
> 15) {
212 res
= ((x
& MASK_SIGN
) != MASK_SIGN
) ? y
: x
; // difference cannot be >10^15
215 // if exp_x is 15 less than exp_y, no need for compensation
216 if (exp_y
- exp_x
> 15) {
217 res
= ((x
& MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
220 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
221 if (exp_x
> exp_y
) { // to simplify the loop below,
223 // otherwise adjust the x significand upwards
224 __mul_64x64_to_128MACH (sig_n_prime
, sig_x
,
225 mult_factor
[exp_x
- exp_y
]);
226 // if postitive, return whichever significand is larger
227 // (converse if negative)
228 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_y
)) {
233 res
= (((sig_n_prime
.w
[1] > 0)
234 || sig_n_prime
.w
[0] > sig_y
) ^ ((x
& MASK_SIGN
) ==
238 // adjust the y significand upwards
239 __mul_64x64_to_128MACH (sig_n_prime
, sig_y
,
240 mult_factor
[exp_y
- exp_x
]);
242 // if postitive, return whichever significand is larger (converse if negative)
243 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_x
)) {
247 res
= (((sig_n_prime
.w
[1] == 0)
248 && (sig_x
> sig_n_prime
.w
[0])) ^ ((x
& MASK_SIGN
) ==
253 /*****************************************************************************
254 * BID64 minimum magnitude function - returns greater of two numbers
255 *****************************************************************************/
257 #if DECIMAL_CALL_BY_REFERENCE
259 bid64_minnum_mag (UINT64
* pres
, UINT64
* px
,
260 UINT64
* py _EXC_FLAGS_PARAM
) {
265 bid64_minnum_mag (UINT64 x
, UINT64 y _EXC_FLAGS_PARAM
) {
273 // check for non-canonical x
274 if ((x
& MASK_NAN
) == MASK_NAN
) { // x is NaN
275 x
= x
& 0xfe03ffffffffffffull
; // clear G6-G12
276 if ((x
& 0x0003ffffffffffffull
) > 999999999999999ull) {
277 x
= x
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
279 } else if ((x
& MASK_INF
) == MASK_INF
) { // check for Infinity
280 x
= x
& (MASK_SIGN
| MASK_INF
);
281 } else { // x is not special
282 // check for non-canonical values - treated as zero
283 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
284 // if the steering bits are 11, then the exponent is G[0:w+1]
285 if (((x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
) >
286 9999999999999999ull) {
288 x
= (x
& MASK_SIGN
) | ((x
& MASK_BINARY_EXPONENT2
) << 2);
293 // check for non-canonical y
294 if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NaN
295 y
= y
& 0xfe03ffffffffffffull
; // clear G6-G12
296 if ((y
& 0x0003ffffffffffffull
) > 999999999999999ull) {
297 y
= y
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
299 } else if ((y
& MASK_INF
) == MASK_INF
) { // check for Infinity
300 y
= y
& (MASK_SIGN
| MASK_INF
);
301 } else { // y is not special
302 // check for non-canonical values - treated as zero
303 if ((y
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
304 // if the steering bits are 11, then the exponent is G[0:w+1]
305 if (((y
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
) >
306 9999999999999999ull) {
308 y
= (y
& MASK_SIGN
) | ((y
& MASK_BINARY_EXPONENT2
) << 2);
314 if ((x
& MASK_NAN
) == MASK_NAN
) { // x is NAN
315 if ((x
& MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
316 // if x is SNAN, then return quiet (x)
317 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
318 x
= x
& 0xfdffffffffffffffull
; // quietize x
320 } else { // x is QNaN
321 if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NAN
322 if ((y
& MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
323 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
331 } else if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
332 if ((y
& MASK_SNAN
) == MASK_SNAN
) {
333 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
334 y
= y
& 0xfdffffffffffffffull
; // quietize y
337 // will return x (which is not NaN)
343 // if all the bits are the same, these numbers are equal, return either number
349 if ((x
& MASK_INF
) == MASK_INF
) {
350 // x is infinity, its magnitude is greater than or equal to y
351 // return x only if y is infinity and x is negative
352 res
= ((x
& MASK_SIGN
) == MASK_SIGN
353 && (y
& MASK_INF
) == MASK_INF
) ? x
: y
;
355 } else if ((y
& MASK_INF
) == MASK_INF
) {
356 // y is infinity, then it must be greater in magnitude, return x
360 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
361 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
362 exp_x
= (x
& MASK_BINARY_EXPONENT2
) >> 51;
363 sig_x
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
365 exp_x
= (x
& MASK_BINARY_EXPONENT1
) >> 53;
366 sig_x
= (x
& MASK_BINARY_SIG1
);
369 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
370 if ((y
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
371 exp_y
= (y
& MASK_BINARY_EXPONENT2
) >> 51;
372 sig_y
= (y
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
374 exp_y
= (y
& MASK_BINARY_EXPONENT1
) >> 53;
375 sig_y
= (y
& MASK_BINARY_SIG1
);
380 // (+ZERO == -ZERO) => therefore
381 // ignore the sign, and neither number is greater
382 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
383 // ignore the exponent field
384 // (Any non-canonical # is considered 0)
386 res
= x
; // x_is_zero, its magnitude must be smaller than y
390 res
= y
; // y_is_zero, its magnitude must be smaller than x
393 // REDUNDANT REPRESENTATIONS (CASE6)
394 // if both components are either bigger or smaller,
395 // it is clear what needs to be done
396 if (sig_x
> sig_y
&& exp_x
>= exp_y
) {
400 if (sig_x
< sig_y
&& exp_x
<= exp_y
) {
404 // if exp_x is 15 greater than exp_y, no need for compensation
405 if (exp_x
- exp_y
> 15) {
406 res
= y
; // difference cannot be greater than 10^15
409 // if exp_x is 15 less than exp_y, no need for compensation
410 if (exp_y
- exp_x
> 15) {
414 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
415 if (exp_x
> exp_y
) { // to simplify the loop below,
416 // otherwise adjust the x significand upwards
417 __mul_64x64_to_128MACH (sig_n_prime
, sig_x
,
418 mult_factor
[exp_x
- exp_y
]);
419 // now, sig_n_prime has: sig_x * 10^(exp_x-exp_y), this is
420 // the compensated signif.
421 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_y
)) {
422 // two numbers are equal, return minNum(x,y)
423 res
= ((y
& MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
426 // now, if compensated_x (sig_n_prime) is greater than y, return y,
427 // otherwise return x
428 res
= ((sig_n_prime
.w
[1] != 0) || sig_n_prime
.w
[0] > sig_y
) ? y
: x
;
431 // exp_y must be greater than exp_x, thus adjust the y significand upwards
432 __mul_64x64_to_128MACH (sig_n_prime
, sig_y
,
433 mult_factor
[exp_y
- exp_x
]);
435 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_x
)) {
436 res
= ((y
& MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
437 // two numbers are equal, return either
441 res
= ((sig_n_prime
.w
[1] == 0) && (sig_x
> sig_n_prime
.w
[0])) ? y
: x
;
445 /*****************************************************************************
446 * BID64 maximum function - returns greater of two numbers
447 *****************************************************************************/
449 #if DECIMAL_CALL_BY_REFERENCE
451 bid64_maxnum (UINT64
* pres
, UINT64
* px
, UINT64
* py _EXC_FLAGS_PARAM
) {
456 bid64_maxnum (UINT64 x
, UINT64 y _EXC_FLAGS_PARAM
) {
463 char x_is_zero
= 0, y_is_zero
= 0;
465 // check for non-canonical x
466 if ((x
& MASK_NAN
) == MASK_NAN
) { // x is NaN
467 x
= x
& 0xfe03ffffffffffffull
; // clear G6-G12
468 if ((x
& 0x0003ffffffffffffull
) > 999999999999999ull) {
469 x
= x
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
471 } else if ((x
& MASK_INF
) == MASK_INF
) { // check for Infinity
472 x
= x
& (MASK_SIGN
| MASK_INF
);
473 } else { // x is not special
474 // check for non-canonical values - treated as zero
475 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
476 // if the steering bits are 11, then the exponent is G[0:w+1]
477 if (((x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
) >
478 9999999999999999ull) {
480 x
= (x
& MASK_SIGN
) | ((x
& MASK_BINARY_EXPONENT2
) << 2);
485 // check for non-canonical y
486 if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NaN
487 y
= y
& 0xfe03ffffffffffffull
; // clear G6-G12
488 if ((y
& 0x0003ffffffffffffull
) > 999999999999999ull) {
489 y
= y
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
491 } else if ((y
& MASK_INF
) == MASK_INF
) { // check for Infinity
492 y
= y
& (MASK_SIGN
| MASK_INF
);
493 } else { // y is not special
494 // check for non-canonical values - treated as zero
495 if ((y
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
496 // if the steering bits are 11, then the exponent is G[0:w+1]
497 if (((y
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
) >
498 9999999999999999ull) {
500 y
= (y
& MASK_SIGN
) | ((y
& MASK_BINARY_EXPONENT2
) << 2);
506 if ((x
& MASK_NAN
) == MASK_NAN
) { // x is NAN
507 if ((x
& MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
508 // if x is SNAN, then return quiet (x)
509 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
510 x
= x
& 0xfdffffffffffffffull
; // quietize x
512 } else { // x is QNaN
513 if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NAN
514 if ((y
& MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
515 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
523 } else if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
524 if ((y
& MASK_SNAN
) == MASK_SNAN
) {
525 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
526 y
= y
& 0xfdffffffffffffffull
; // quietize y
529 // will return x (which is not NaN)
535 // if all the bits are the same, these numbers are equal (not Greater).
541 if ((x
& MASK_INF
) == MASK_INF
) {
542 // if x is neg infinity, there is no way it is greater than y, return y
543 // x is pos infinity, it is greater, unless y is positive infinity =>
544 // return y!=pos_infinity
545 if (((x
& MASK_SIGN
) == MASK_SIGN
)) {
549 res
= (((y
& MASK_INF
) != MASK_INF
)
550 || ((y
& MASK_SIGN
) == MASK_SIGN
)) ? x
: y
;
553 } else if ((y
& MASK_INF
) == MASK_INF
) {
554 // x is finite, so if y is positive infinity, then x is less, return y
555 // if y is negative infinity, then x is greater, return x
556 res
= ((y
& MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
559 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
560 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
561 exp_x
= (x
& MASK_BINARY_EXPONENT2
) >> 51;
562 sig_x
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
564 exp_x
= (x
& MASK_BINARY_EXPONENT1
) >> 53;
565 sig_x
= (x
& MASK_BINARY_SIG1
);
568 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
569 if ((y
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
570 exp_y
= (y
& MASK_BINARY_EXPONENT2
) >> 51;
571 sig_y
= (y
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
573 exp_y
= (y
& MASK_BINARY_EXPONENT1
) >> 53;
574 sig_y
= (y
& MASK_BINARY_SIG1
);
579 // (+ZERO == -ZERO) => therefore
580 // ignore the sign, and neither number is greater
581 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
582 // ignore the exponent field
583 // (Any non-canonical # is considered 0)
591 if (x_is_zero
&& y_is_zero
) {
592 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
595 } else if (x_is_zero
) {
596 // is x is zero, it is greater if Y is negative
597 res
= ((y
& MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
599 } else if (y_is_zero
) {
600 // is y is zero, X is greater if it is positive
601 res
= ((x
& MASK_SIGN
) != MASK_SIGN
) ? x
: y
;;
604 // OPPOSITE SIGN (CASE5)
605 // now, if the sign bits differ, x is greater if y is negative
606 if (((x
^ y
) & MASK_SIGN
) == MASK_SIGN
) {
607 res
= ((y
& MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
610 // REDUNDANT REPRESENTATIONS (CASE6)
612 // if both components are either bigger or smaller,
613 // it is clear what needs to be done
614 if (sig_x
> sig_y
&& exp_x
>= exp_y
) {
615 res
= ((x
& MASK_SIGN
) != MASK_SIGN
) ? x
: y
;
618 if (sig_x
< sig_y
&& exp_x
<= exp_y
) {
619 res
= ((x
& MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
622 // if exp_x is 15 greater than exp_y, no need for compensation
623 if (exp_x
- exp_y
> 15) {
624 res
= ((x
& MASK_SIGN
) != MASK_SIGN
) ? x
: y
;
625 // difference cannot be > 10^15
628 // if exp_x is 15 less than exp_y, no need for compensation
629 if (exp_y
- exp_x
> 15) {
630 res
= ((x
& MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
633 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
634 if (exp_x
> exp_y
) { // to simplify the loop below,
635 // otherwise adjust the x significand upwards
636 __mul_64x64_to_128MACH (sig_n_prime
, sig_x
,
637 mult_factor
[exp_x
- exp_y
]);
638 // if postitive, return whichever significand is larger
639 // (converse if negative)
640 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_y
)) {
644 res
= (((sig_n_prime
.w
[1] > 0)
645 || sig_n_prime
.w
[0] > sig_y
) ^ ((x
& MASK_SIGN
) ==
649 // adjust the y significand upwards
650 __mul_64x64_to_128MACH (sig_n_prime
, sig_y
,
651 mult_factor
[exp_y
- exp_x
]);
653 // if postitive, return whichever significand is larger (converse if negative)
654 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_x
)) {
658 res
= (((sig_n_prime
.w
[1] == 0)
659 && (sig_x
> sig_n_prime
.w
[0])) ^ ((x
& MASK_SIGN
) ==
664 /*****************************************************************************
665 * BID64 maximum magnitude function - returns greater of two numbers
666 *****************************************************************************/
668 #if DECIMAL_CALL_BY_REFERENCE
670 bid64_maxnum_mag (UINT64
* pres
, UINT64
* px
,
671 UINT64
* py _EXC_FLAGS_PARAM
) {
676 bid64_maxnum_mag (UINT64 x
, UINT64 y _EXC_FLAGS_PARAM
) {
684 // check for non-canonical x
685 if ((x
& MASK_NAN
) == MASK_NAN
) { // x is NaN
686 x
= x
& 0xfe03ffffffffffffull
; // clear G6-G12
687 if ((x
& 0x0003ffffffffffffull
) > 999999999999999ull) {
688 x
= x
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
690 } else if ((x
& MASK_INF
) == MASK_INF
) { // check for Infinity
691 x
= x
& (MASK_SIGN
| MASK_INF
);
692 } else { // x is not special
693 // check for non-canonical values - treated as zero
694 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
695 // if the steering bits are 11, then the exponent is G[0:w+1]
696 if (((x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
) >
697 9999999999999999ull) {
699 x
= (x
& MASK_SIGN
) | ((x
& MASK_BINARY_EXPONENT2
) << 2);
704 // check for non-canonical y
705 if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NaN
706 y
= y
& 0xfe03ffffffffffffull
; // clear G6-G12
707 if ((y
& 0x0003ffffffffffffull
) > 999999999999999ull) {
708 y
= y
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
710 } else if ((y
& MASK_INF
) == MASK_INF
) { // check for Infinity
711 y
= y
& (MASK_SIGN
| MASK_INF
);
712 } else { // y is not special
713 // check for non-canonical values - treated as zero
714 if ((y
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
715 // if the steering bits are 11, then the exponent is G[0:w+1]
716 if (((y
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
) >
717 9999999999999999ull) {
719 y
= (y
& MASK_SIGN
) | ((y
& MASK_BINARY_EXPONENT2
) << 2);
725 if ((x
& MASK_NAN
) == MASK_NAN
) { // x is NAN
726 if ((x
& MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
727 // if x is SNAN, then return quiet (x)
728 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
729 x
= x
& 0xfdffffffffffffffull
; // quietize x
731 } else { // x is QNaN
732 if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NAN
733 if ((y
& MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
734 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
742 } else if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
743 if ((y
& MASK_SNAN
) == MASK_SNAN
) {
744 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
745 y
= y
& 0xfdffffffffffffffull
; // quietize y
748 // will return x (which is not NaN)
754 // if all the bits are the same, these numbers are equal, return either number
760 if ((x
& MASK_INF
) == MASK_INF
) {
761 // x is infinity, its magnitude is greater than or equal to y
762 // return y as long as x isn't negative infinity
763 res
= ((x
& MASK_SIGN
) == MASK_SIGN
764 && (y
& MASK_INF
) == MASK_INF
) ? y
: x
;
766 } else if ((y
& MASK_INF
) == MASK_INF
) {
767 // y is infinity, then it must be greater in magnitude
771 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
772 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
773 exp_x
= (x
& MASK_BINARY_EXPONENT2
) >> 51;
774 sig_x
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
776 exp_x
= (x
& MASK_BINARY_EXPONENT1
) >> 53;
777 sig_x
= (x
& MASK_BINARY_SIG1
);
780 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
781 if ((y
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
782 exp_y
= (y
& MASK_BINARY_EXPONENT2
) >> 51;
783 sig_y
= (y
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
785 exp_y
= (y
& MASK_BINARY_EXPONENT1
) >> 53;
786 sig_y
= (y
& MASK_BINARY_SIG1
);
791 // (+ZERO == -ZERO) => therefore
792 // ignore the sign, and neither number is greater
793 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
794 // ignore the exponent field
795 // (Any non-canonical # is considered 0)
797 res
= y
; // x_is_zero, its magnitude must be smaller than y
801 res
= x
; // y_is_zero, its magnitude must be smaller than x
804 // REDUNDANT REPRESENTATIONS (CASE6)
805 // if both components are either bigger or smaller,
806 // it is clear what needs to be done
807 if (sig_x
> sig_y
&& exp_x
>= exp_y
) {
811 if (sig_x
< sig_y
&& exp_x
<= exp_y
) {
815 // if exp_x is 15 greater than exp_y, no need for compensation
816 if (exp_x
- exp_y
> 15) {
817 res
= x
; // difference cannot be greater than 10^15
820 // if exp_x is 15 less than exp_y, no need for compensation
821 if (exp_y
- exp_x
> 15) {
825 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
826 if (exp_x
> exp_y
) { // to simplify the loop below,
827 // otherwise adjust the x significand upwards
828 __mul_64x64_to_128MACH (sig_n_prime
, sig_x
,
829 mult_factor
[exp_x
- exp_y
]);
830 // now, sig_n_prime has: sig_x * 10^(exp_x-exp_y),
831 // this is the compensated signif.
832 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_y
)) {
833 // two numbers are equal, return maxNum(x,y)
834 res
= ((y
& MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
837 // now, if compensated_x (sig_n_prime) is greater than y return y,
838 // otherwise return x
839 res
= ((sig_n_prime
.w
[1] != 0) || sig_n_prime
.w
[0] > sig_y
) ? x
: y
;
842 // exp_y must be greater than exp_x, thus adjust the y significand upwards
843 __mul_64x64_to_128MACH (sig_n_prime
, sig_y
,
844 mult_factor
[exp_y
- exp_x
]);
846 if (sig_n_prime
.w
[1] == 0 && (sig_n_prime
.w
[0] == sig_x
)) {
847 res
= ((y
& MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
848 // two numbers are equal, return either
852 res
= ((sig_n_prime
.w
[1] == 0) && (sig_x
> sig_n_prime
.w
[0])) ? x
: y
;