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
,
39 UINT128
* py _EXC_FLAGS_PARAM
) {
44 bid128_minnum (UINT128 x
, UINT128 y _EXC_FLAGS_PARAM
) {
51 UINT192 sig_n_prime192
;
52 UINT256 sig_n_prime256
;
53 char x_is_zero
= 0, y_is_zero
= 0;
58 // check for non-canonical x
59 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
60 x
.w
[1] = x
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
61 // check for non-canonical NaN payload
62 if (((x
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
63 (((x
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
64 (x
.w
[0] > 0x38c15b09ffffffffull
))) {
65 x
.w
[1] = x
.w
[1] & 0xffffc00000000000ull
;
68 } else if ((x
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // x = inf
69 x
.w
[1] = x
.w
[1] & (MASK_SIGN
| MASK_INF
);
71 } else { // x is not special
72 // check for non-canonical values - treated as zero
73 if ((x
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
75 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | ((x
.w
[1] << 2) & MASK_EXP
);
77 } else { // G0_G1 != 11
78 if ((x
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
79 ((x
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
80 && x
.w
[0] > 0x378d8e63ffffffffull
)) {
81 // x is non-canonical if coefficient is larger than 10^34 -1
82 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | (x
.w
[1] & MASK_EXP
);
89 // check for non-canonical y
90 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
91 y
.w
[1] = y
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
92 // check for non-canonical NaN payload
93 if (((y
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
94 (((y
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
95 (y
.w
[0] > 0x38c15b09ffffffffull
))) {
96 y
.w
[1] = y
.w
[1] & 0xffffc00000000000ull
;
99 } else if ((y
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // y = inf
100 y
.w
[1] = y
.w
[1] & (MASK_SIGN
| MASK_INF
);
102 } else { // y is not special
103 // check for non-canonical values - treated as zero
104 if ((y
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
106 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | ((y
.w
[1] << 2) & MASK_EXP
);
108 } else { // G0_G1 != 11
109 if ((y
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
110 ((y
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
111 && y
.w
[0] > 0x378d8e63ffffffffull
)) {
112 // y is non-canonical if coefficient is larger than 10^34 -1
113 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | (y
.w
[1] & MASK_EXP
);
115 } else { // canonical
122 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
123 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
124 // if x is SNAN, then return quiet (x)
125 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
126 x
.w
[1] = x
.w
[1] & 0xfdffffffffffffffull
; // quietize x
128 } else { // x is QNaN
129 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
130 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
131 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
139 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
140 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) {
141 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
142 y
.w
[1] = y
.w
[1] & 0xfdffffffffffffffull
; // quietize y
145 // will return x (which is not NaN)
151 // if all the bits are the same, these numbers are equal (not Greater).
152 if (x
.w
[0] == y
.w
[0] && x
.w
[1] == y
.w
[1]) {
157 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
158 // if x is neg infinity, there is no way it is greater than y, return 0
159 res
= (((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
)) ? x
: y
;
161 } else if ((y
.w
[1] & MASK_INF
) == MASK_INF
) {
162 // x is finite, so if y is positive infinity, then x is less, return 0
163 // if y is negative infinity, then x is greater, return 1
164 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
168 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
170 exp_x
= (x
.w
[1] >> 49) & 0x000000000003fffull
;
173 exp_y
= (y
.w
[1] >> 49) & 0x0000000000003fffull
;
174 sig_y
.w
[1] = y
.w
[1] & 0x0001ffffffffffffull
;
179 // (+ZERO == -ZERO) => therefore ignore the sign
180 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => ignore the exponent
182 // (Any non-canonical # is considered 0)
183 if ((sig_x
.w
[1] == 0) && (sig_x
.w
[0] == 0)) {
186 if ((sig_y
.w
[1] == 0) && (sig_y
.w
[0] == 0)) {
190 if (x_is_zero
&& y_is_zero
) {
191 // if both numbers are zero, neither is greater => return either number
194 } else if (x_is_zero
) {
195 // is x is zero, it is greater if Y is negative
196 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
198 } else if (y_is_zero
) {
199 // is y is zero, X is greater if it is positive
200 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
) ? y
: x
;
203 // OPPOSITE SIGN (CASE5)
204 // now, if the sign bits differ, x is greater if y is negative
205 if (((x
.w
[1] ^ y
.w
[1]) & MASK_SIGN
) == MASK_SIGN
) {
206 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
209 // REDUNDANT REPRESENTATIONS (CASE6)
210 // if exponents are the same, then we have a simple comparison of
212 if (exp_y
== exp_x
) {
213 res
= (((sig_x
.w
[1] > sig_y
.w
[1])
214 || (sig_x
.w
[1] == sig_y
.w
[1]
215 && sig_x
.w
[0] >= sig_y
.w
[0])) ^ ((x
.w
[1] & MASK_SIGN
) ==
219 // if both components are either bigger or smaller, it is clear what
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
;
226 if (sig_x
.w
[1] <= sig_y
.w
[1] && sig_x
.w
[0] <= sig_y
.w
[0]
228 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
232 diff
= exp_x
- exp_y
;
234 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
235 if (diff
> 0) { // to simplify the loop below,
236 // if exp_x is 33 greater than exp_y, no need for compensation
238 // difference cannot be greater than 10^33
239 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
) ? y
: x
;
242 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
243 __mul_128x128_to_256 (sig_n_prime256
, sig_x
, ten2k128
[diff
- 20]);
244 // if postitive, return whichever significand is larger
245 // (converse if negative)
246 res
= ((((sig_n_prime256
.w
[3] > 0) || sig_n_prime256
.w
[2] > 0)
247 || (sig_n_prime256
.w
[1] > sig_y
.w
[1])
248 || (sig_n_prime256
.w
[1] == sig_y
.w
[1]
249 && sig_n_prime256
.w
[0] >
250 sig_y
.w
[0])) ^ ((y
.w
[1] & MASK_SIGN
) ==
254 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_x
);
255 // if postitive, return whichever significand is larger
256 // (converse if negative)
258 (((sig_n_prime192
.w
[2] > 0) || (sig_n_prime192
.w
[1] > sig_y
.w
[1])
259 || (sig_n_prime192
.w
[1] == sig_y
.w
[1]
260 && sig_n_prime192
.w
[0] >
261 sig_y
.w
[0])) ^ ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
)) ? y
: x
;
264 diff
= exp_y
- exp_x
;
265 // if exp_x is 33 less than exp_y, no need for compensation
267 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
270 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
271 // adjust the y significand upwards
272 __mul_128x128_to_256 (sig_n_prime256
, sig_y
, ten2k128
[diff
- 20]);
273 // if postitive, return whichever significand is larger
274 // (converse if negative)
276 ((sig_n_prime256
.w
[3] != 0 || sig_n_prime256
.w
[2] != 0
277 || (sig_n_prime256
.w
[1] > sig_x
.w
[1]
278 || (sig_n_prime256
.w
[1] == sig_x
.w
[1]
279 && sig_n_prime256
.w
[0] >
280 sig_x
.w
[0]))) ^ ((x
.w
[1] & MASK_SIGN
) ==
284 // adjust the y significand upwards
285 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_y
);
286 // if postitive, return whichever significand is larger (converse if negative)
288 ((sig_n_prime192
.w
[2] != 0
289 || (sig_n_prime192
.w
[1] > sig_x
.w
[1]
290 || (sig_n_prime192
.w
[1] == sig_x
.w
[1]
291 && sig_n_prime192
.w
[0] > sig_x
.w
[0])))
292 ^ ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
)) ? x
: y
;
296 /*****************************************************************************
297 * BID128 minimum magnitude function - returns greater of two numbers
298 *****************************************************************************/
300 #if DECIMAL_CALL_BY_REFERENCE
302 bid128_minnum_mag (UINT128
* pres
, UINT128
* px
,
303 UINT128
* py _EXC_FLAGS_PARAM
) {
308 bid128_minnum_mag (UINT128 x
, UINT128 y _EXC_FLAGS_PARAM
) {
314 UINT128 sig_x
, sig_y
;
315 UINT192 sig_n_prime192
;
316 UINT256 sig_n_prime256
;
321 // check for non-canonical x
322 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
323 x
.w
[1] = x
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
324 // check for non-canonical NaN payload
325 if (((x
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
326 (((x
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
327 (x
.w
[0] > 0x38c15b09ffffffffull
))) {
328 x
.w
[1] = x
.w
[1] & 0xffffc00000000000ull
;
331 } else if ((x
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // x = inf
332 x
.w
[1] = x
.w
[1] & (MASK_SIGN
| MASK_INF
);
334 } else { // x is not special
335 // check for non-canonical values - treated as zero
336 if ((x
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
338 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | ((x
.w
[1] << 2) & MASK_EXP
);
340 } else { // G0_G1 != 11
341 if ((x
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
342 ((x
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
343 && x
.w
[0] > 0x378d8e63ffffffffull
)) {
344 // x is non-canonical if coefficient is larger than 10^34 -1
345 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | (x
.w
[1] & MASK_EXP
);
347 } else { // canonical
352 // check for non-canonical y
353 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
354 y
.w
[1] = y
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
355 // check for non-canonical NaN payload
356 if (((y
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
357 (((y
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
358 (y
.w
[0] > 0x38c15b09ffffffffull
))) {
359 y
.w
[1] = y
.w
[1] & 0xffffc00000000000ull
;
362 } else if ((y
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // y = inf
363 y
.w
[1] = y
.w
[1] & (MASK_SIGN
| MASK_INF
);
365 } else { // y is not special
366 // check for non-canonical values - treated as zero
367 if ((y
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
369 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | ((y
.w
[1] << 2) & MASK_EXP
);
371 } else { // G0_G1 != 11
372 if ((y
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
373 ((y
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
374 && y
.w
[0] > 0x378d8e63ffffffffull
)) {
375 // y is non-canonical if coefficient is larger than 10^34 -1
376 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | (y
.w
[1] & MASK_EXP
);
378 } else { // canonical
385 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
386 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
387 // if x is SNAN, then return quiet (x)
388 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
389 x
.w
[1] = x
.w
[1] & 0xfdffffffffffffffull
; // quietize x
391 } else { // x is QNaN
392 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
393 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
394 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
402 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
403 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) {
404 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
405 y
.w
[1] = y
.w
[1] & 0xfdffffffffffffffull
; // quietize y
408 // will return x (which is not NaN)
414 // if all the bits are the same, these numbers are equal (not Greater).
415 if (x
.w
[0] == y
.w
[0] && x
.w
[1] == y
.w
[1]) {
420 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
421 // if x infinity, it has maximum magnitude.
422 // Check if magnitudes are equal. If x is negative, return it.
423 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
424 && (y
.w
[1] & MASK_INF
) == MASK_INF
) ? x
: y
;
426 } else if ((y
.w
[1] & MASK_INF
) == MASK_INF
) {
427 // x is finite, so if y is infinity, then x is less in magnitude
432 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
434 exp_x
= (x
.w
[1] >> 49) & 0x000000000003fffull
;
437 exp_y
= (y
.w
[1] >> 49) & 0x0000000000003fffull
;
438 sig_y
.w
[1] = y
.w
[1] & 0x0001ffffffffffffull
;
443 // (+ZERO == -ZERO) => therefore ignore the sign
444 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
445 // therefore ignore the exponent field
446 // (Any non-canonical # is considered 0)
447 if ((sig_x
.w
[1] == 0) && (sig_x
.w
[0] == 0)) {
451 if ((sig_y
.w
[1] == 0) && (sig_y
.w
[0] == 0)) {
455 // REDUNDANT REPRESENTATIONS (CASE6)
456 // check if exponents are the same and significands are the same
457 if (exp_y
== exp_x
&& sig_x
.w
[1] == sig_y
.w
[1]
458 && sig_x
.w
[0] == sig_y
.w
[0]) {
459 if (x
.w
[1] & 0x8000000000000000ull
) { // x is negative
466 } else if (((sig_x
.w
[1] > sig_y
.w
[1] || (sig_x
.w
[1] == sig_y
.w
[1]
467 && sig_x
.w
[0] > sig_y
.w
[0]))
469 || ((sig_x
.w
[1] > sig_y
.w
[1]
470 || (sig_x
.w
[1] == sig_y
.w
[1]
471 && sig_x
.w
[0] >= sig_y
.w
[0]))
473 // if both components are either bigger or smaller, it is clear what
474 // needs to be done; also if the magnitudes are equal
477 } else if (((sig_y
.w
[1] > sig_x
.w
[1] || (sig_y
.w
[1] == sig_x
.w
[1]
478 && sig_y
.w
[0] > sig_x
.w
[0]))
480 || ((sig_y
.w
[1] > sig_x
.w
[1]
481 || (sig_y
.w
[1] == sig_x
.w
[1]
482 && sig_y
.w
[0] >= sig_x
.w
[0]))
489 diff
= exp_x
- exp_y
;
490 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
491 if (diff
> 0) { // to simplify the loop below,
492 // if exp_x is 33 greater than exp_y, no need for compensation
494 res
= y
; // difference cannot be greater than 10^33
497 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
498 __mul_128x128_to_256 (sig_n_prime256
, sig_x
, ten2k128
[diff
- 20]);
499 // if positive, return whichever significand is larger
500 // (converse if negative)
501 if (sig_n_prime256
.w
[3] == 0 && (sig_n_prime256
.w
[2] == 0)
502 && sig_n_prime256
.w
[1] == sig_y
.w
[1]
503 && (sig_n_prime256
.w
[0] == sig_y
.w
[0])) {
504 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
; // if equal
507 res
= (((sig_n_prime256
.w
[3] > 0) || sig_n_prime256
.w
[2] > 0)
508 || (sig_n_prime256
.w
[1] > sig_y
.w
[1])
509 || (sig_n_prime256
.w
[1] == sig_y
.w
[1]
510 && sig_n_prime256
.w
[0] > sig_y
.w
[0])) ? y
: x
;
513 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_x
);
514 // if positive, return whichever significand is larger
515 // (converse if negative)
516 if ((sig_n_prime192
.w
[2] == 0) && sig_n_prime192
.w
[1] == sig_y
.w
[1]
517 && (sig_n_prime192
.w
[0] == sig_y
.w
[0])) {
518 // if = in magnitude, return +, (if possible)
519 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
522 res
= ((sig_n_prime192
.w
[2] > 0)
523 || (sig_n_prime192
.w
[1] > sig_y
.w
[1])
524 || (sig_n_prime192
.w
[1] == sig_y
.w
[1]
525 && sig_n_prime192
.w
[0] > sig_y
.w
[0])) ? y
: x
;
528 diff
= exp_y
- exp_x
;
529 // if exp_x is 33 less than exp_y, no need for compensation
534 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
535 // adjust the y significand upwards
536 __mul_128x128_to_256 (sig_n_prime256
, sig_y
, ten2k128
[diff
- 20]);
537 // if positive, return whichever significand is larger
538 // (converse if negative)
539 if (sig_n_prime256
.w
[3] == 0 && (sig_n_prime256
.w
[2] == 0)
540 && sig_n_prime256
.w
[1] == sig_x
.w
[1]
541 && (sig_n_prime256
.w
[0] == sig_x
.w
[0])) {
542 // if = in magnitude, return +, (if possible)
543 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
546 res
= (sig_n_prime256
.w
[3] == 0 && sig_n_prime256
.w
[2] == 0
547 && (sig_n_prime256
.w
[1] < sig_x
.w
[1]
548 || (sig_n_prime256
.w
[1] == sig_x
.w
[1]
549 && sig_n_prime256
.w
[0] < sig_x
.w
[0]))) ? y
: x
;
552 // adjust the y significand upwards
553 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_y
);
554 // if positive, return whichever significand is larger (converse if negative)
555 if ((sig_n_prime192
.w
[2] == 0) && sig_n_prime192
.w
[1] == sig_x
.w
[1]
556 && (sig_n_prime192
.w
[0] == sig_x
.w
[0])) {
557 // if = in magnitude, return +, if possible)
558 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
561 res
= (sig_n_prime192
.w
[2] == 0
562 && (sig_n_prime192
.w
[1] < sig_x
.w
[1]
563 || (sig_n_prime192
.w
[1] == sig_x
.w
[1]
564 && sig_n_prime192
.w
[0] < sig_x
.w
[0]))) ? y
: x
;
568 /*****************************************************************************
569 * BID128 maximum function - returns greater of two numbers
570 *****************************************************************************/
572 #if DECIMAL_CALL_BY_REFERENCE
574 bid128_maxnum (UINT128
* pres
, UINT128
* px
,
575 UINT128
* py _EXC_FLAGS_PARAM
) {
580 bid128_maxnum (UINT128 x
, UINT128 y _EXC_FLAGS_PARAM
) {
586 UINT128 sig_x
, sig_y
;
587 UINT192 sig_n_prime192
;
588 UINT256 sig_n_prime256
;
589 char x_is_zero
= 0, y_is_zero
= 0;
594 // check for non-canonical x
595 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
596 x
.w
[1] = x
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
597 // check for non-canonical NaN payload
598 if (((x
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
599 (((x
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
600 (x
.w
[0] > 0x38c15b09ffffffffull
))) {
601 x
.w
[1] = x
.w
[1] & 0xffffc00000000000ull
;
604 } else if ((x
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // x = inf
605 x
.w
[1] = x
.w
[1] & (MASK_SIGN
| MASK_INF
);
607 } else { // x is not special
608 // check for non-canonical values - treated as zero
609 if ((x
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
611 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | ((x
.w
[1] << 2) & MASK_EXP
);
613 } else { // G0_G1 != 11
614 if ((x
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
615 ((x
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
616 && x
.w
[0] > 0x378d8e63ffffffffull
)) {
617 // x is non-canonical if coefficient is larger than 10^34 -1
618 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | (x
.w
[1] & MASK_EXP
);
620 } else { // canonical
625 // check for non-canonical y
626 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
627 y
.w
[1] = y
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
628 // check for non-canonical NaN payload
629 if (((y
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
630 (((y
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
631 (y
.w
[0] > 0x38c15b09ffffffffull
))) {
632 y
.w
[1] = y
.w
[1] & 0xffffc00000000000ull
;
635 } else if ((y
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // y = inf
636 y
.w
[1] = y
.w
[1] & (MASK_SIGN
| MASK_INF
);
638 } else { // y is not special
639 // check for non-canonical values - treated as zero
640 if ((y
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
642 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | ((y
.w
[1] << 2) & MASK_EXP
);
644 } else { // G0_G1 != 11
645 if ((y
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
646 ((y
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
647 && y
.w
[0] > 0x378d8e63ffffffffull
)) {
648 // y is non-canonical if coefficient is larger than 10^34 -1
649 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | (y
.w
[1] & MASK_EXP
);
651 } else { // canonical
658 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
659 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
660 // if x is SNAN, then return quiet (x)
661 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
662 x
.w
[1] = x
.w
[1] & 0xfdffffffffffffffull
; // quietize x
664 } else { // x is QNaN
665 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
666 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
667 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
675 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
676 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) {
677 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
678 y
.w
[1] = y
.w
[1] & 0xfdffffffffffffffull
; // quietize y
681 // will return x (which is not NaN)
687 // if all the bits are the same, these numbers are equal (not Greater).
688 if (x
.w
[0] == y
.w
[0] && x
.w
[1] == y
.w
[1]) {
693 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
694 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? y
: x
;
696 } else if ((y
.w
[1] & MASK_INF
) == MASK_INF
) {
697 // x is finite, so if y is positive infinity, then x is less, return 0
698 // if y is negative infinity, then x is greater, return 1
699 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
703 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
705 exp_x
= (x
.w
[1] >> 49) & 0x000000000003fffull
;
708 exp_y
= (y
.w
[1] >> 49) & 0x0000000000003fffull
;
709 sig_y
.w
[1] = y
.w
[1] & 0x0001ffffffffffffull
;
714 // (+ZERO == -ZERO) => therefore ignore the sign
715 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
716 // therefore ignore the exponent field
717 // (Any non-canonical # is considered 0)
718 if ((sig_x
.w
[1] == 0) && (sig_x
.w
[0] == 0)) {
721 if ((sig_y
.w
[1] == 0) && (sig_y
.w
[0] == 0)) {
725 if (x_is_zero
&& y_is_zero
) {
726 // if both numbers are zero, neither is greater => return either number
729 } else if (x_is_zero
) {
730 // is x is zero, it is greater if Y is negative
731 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
733 } else if (y_is_zero
) {
734 // is y is zero, X is greater if it is positive
735 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
) ? x
: y
;
738 // OPPOSITE SIGN (CASE5)
739 // now, if the sign bits differ, x is greater if y is negative
740 if (((x
.w
[1] ^ y
.w
[1]) & MASK_SIGN
) == MASK_SIGN
) {
741 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
744 // REDUNDANT REPRESENTATIONS (CASE6)
745 // if exponents are the same, then we have a simple comparison of
747 if (exp_y
== exp_x
) {
748 res
= (((sig_x
.w
[1] > sig_y
.w
[1]) || (sig_x
.w
[1] == sig_y
.w
[1] &&
749 sig_x
.w
[0] >= sig_y
.w
[0])) ^
750 ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
)) ? x
: y
;
753 // if both components are either bigger or smaller, it is clear what
755 if ((sig_x
.w
[1] > sig_y
.w
[1]
756 || (sig_x
.w
[1] == sig_y
.w
[1] && sig_x
.w
[0] > sig_y
.w
[0]))
758 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
) ? x
: y
;
761 if ((sig_x
.w
[1] < sig_y
.w
[1]
762 || (sig_x
.w
[1] == sig_y
.w
[1] && sig_x
.w
[0] < sig_y
.w
[0]))
764 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
767 diff
= exp_x
- exp_y
;
768 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
769 if (diff
> 0) { // to simplify the loop below,
770 // if exp_x is 33 greater than exp_y, no need for compensation
772 // difference cannot be greater than 10^33
773 res
= ((x
.w
[1] & MASK_SIGN
) != MASK_SIGN
) ? x
: y
;
776 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
777 __mul_128x128_to_256 (sig_n_prime256
, sig_x
, ten2k128
[diff
- 20]);
778 // if postitive, return whichever significand is larger
779 // (converse if negative)
780 res
= ((((sig_n_prime256
.w
[3] > 0) || sig_n_prime256
.w
[2] > 0)
781 || (sig_n_prime256
.w
[1] > sig_y
.w
[1])
782 || (sig_n_prime256
.w
[1] == sig_y
.w
[1]
783 && sig_n_prime256
.w
[0] >
784 sig_y
.w
[0])) ^ ((y
.w
[1] & MASK_SIGN
) ==
788 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_x
);
789 // if postitive, return whichever significand is larger
790 // (converse if negative)
792 (((sig_n_prime192
.w
[2] > 0) || (sig_n_prime192
.w
[1] > sig_y
.w
[1])
793 || (sig_n_prime192
.w
[1] == sig_y
.w
[1]
794 && sig_n_prime192
.w
[0] >
795 sig_y
.w
[0])) ^ ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
)) ? x
: y
;
798 diff
= exp_y
- exp_x
;
799 // if exp_x is 33 less than exp_y, no need for compensation
801 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
804 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
805 // adjust the y significand upwards
806 __mul_128x128_to_256 (sig_n_prime256
, sig_y
, ten2k128
[diff
- 20]);
807 // if postitive, return whichever significand is larger
808 // (converse if negative)
810 ((sig_n_prime256
.w
[3] != 0 || sig_n_prime256
.w
[2] != 0
811 || (sig_n_prime256
.w
[1] > sig_x
.w
[1]
812 || (sig_n_prime256
.w
[1] == sig_x
.w
[1]
813 && sig_n_prime256
.w
[0] >
814 sig_x
.w
[0]))) ^ ((x
.w
[1] & MASK_SIGN
) !=
818 // adjust the y significand upwards
819 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_y
);
820 // if postitive, return whichever significand is larger (converse if negative)
822 ((sig_n_prime192
.w
[2] != 0
823 || (sig_n_prime192
.w
[1] > sig_x
.w
[1]
824 || (sig_n_prime192
.w
[1] == sig_x
.w
[1]
825 && sig_n_prime192
.w
[0] >
826 sig_x
.w
[0]))) ^ ((y
.w
[1] & MASK_SIGN
) !=
831 /*****************************************************************************
832 * BID128 maximum magnitude function - returns greater of two numbers
833 *****************************************************************************/
835 #if DECIMAL_CALL_BY_REFERENCE
837 bid128_maxnum_mag (UINT128
* pres
, UINT128
* px
,
838 UINT128
* py _EXC_FLAGS_PARAM
) {
843 bid128_maxnum_mag (UINT128 x
, UINT128 y _EXC_FLAGS_PARAM
) {
849 UINT128 sig_x
, sig_y
;
850 UINT192 sig_n_prime192
;
851 UINT256 sig_n_prime256
;
856 // check for non-canonical x
857 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
858 x
.w
[1] = x
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
859 // check for non-canonical NaN payload
860 if (((x
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
861 (((x
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
862 (x
.w
[0] > 0x38c15b09ffffffffull
))) {
863 x
.w
[1] = x
.w
[1] & 0xffffc00000000000ull
;
866 } else if ((x
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // x = inf
867 x
.w
[1] = x
.w
[1] & (MASK_SIGN
| MASK_INF
);
869 } else { // x is not special
870 // check for non-canonical values - treated as zero
871 if ((x
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
873 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | ((x
.w
[1] << 2) & MASK_EXP
);
875 } else { // G0_G1 != 11
876 if ((x
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
877 ((x
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
878 && x
.w
[0] > 0x378d8e63ffffffffull
)) {
879 // x is non-canonical if coefficient is larger than 10^34 -1
880 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | (x
.w
[1] & MASK_EXP
);
882 } else { // canonical
887 // check for non-canonical y
888 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
889 y
.w
[1] = y
.w
[1] & 0xfe003fffffffffffull
; // clear out G[6]-G[16]
890 // check for non-canonical NaN payload
891 if (((y
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
892 (((y
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
) &&
893 (y
.w
[0] > 0x38c15b09ffffffffull
))) {
894 y
.w
[1] = y
.w
[1] & 0xffffc00000000000ull
;
897 } else if ((y
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // y = inf
898 y
.w
[1] = y
.w
[1] & (MASK_SIGN
| MASK_INF
);
900 } else { // y is not special
901 // check for non-canonical values - treated as zero
902 if ((y
.w
[1] & MASK_STEERING_BITS
) == MASK_STEERING_BITS
) { // G0_G1=11
904 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | ((y
.w
[1] << 2) & MASK_EXP
);
906 } else { // G0_G1 != 11
907 if ((y
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
908 ((y
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
&&
909 y
.w
[0] > 0x378d8e63ffffffffull
)) {
910 // y is non-canonical if coefficient is larger than 10^34 -1
911 y
.w
[1] = (y
.w
[1] & MASK_SIGN
) | (y
.w
[1] & MASK_EXP
);
913 } else { // canonical
920 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
921 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNaN
922 // if x is SNAN, then return quiet (x)
923 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
924 x
.w
[1] = x
.w
[1] & 0xfdffffffffffffffull
; // quietize x
926 } else { // x is QNaN
927 if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
928 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
929 *pfpsf
|= INVALID_EXCEPTION
; // set invalid flag
937 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NaN, but x is not
938 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) {
939 *pfpsf
|= INVALID_EXCEPTION
; // set exception if SNaN
940 y
.w
[1] = y
.w
[1] & 0xfdffffffffffffffull
; // quietize y
943 // will return x (which is not NaN)
949 // if all the bits are the same, these numbers are equal (not Greater).
950 if (x
.w
[0] == y
.w
[0] && x
.w
[1] == y
.w
[1]) {
955 if ((x
.w
[1] & MASK_INF
) == MASK_INF
) {
956 // if x infinity, it has maximum magnitude
957 res
= ((x
.w
[1] & MASK_SIGN
) == MASK_SIGN
958 && (y
.w
[1] & MASK_INF
) == MASK_INF
) ? y
: x
;
960 } else if ((y
.w
[1] & MASK_INF
) == MASK_INF
) {
961 // x is finite, so if y is positive infinity, then x is less, return 0
962 // if y is negative infinity, then x is greater, return 1
967 sig_x
.w
[1] = x
.w
[1] & 0x0001ffffffffffffull
;
969 exp_x
= (x
.w
[1] >> 49) & 0x000000000003fffull
;
972 exp_y
= (y
.w
[1] >> 49) & 0x0000000000003fffull
;
973 sig_y
.w
[1] = y
.w
[1] & 0x0001ffffffffffffull
;
978 // (+ZERO == -ZERO) => therefore ignore the sign
979 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
980 // therefore ignore the exponent field
981 // (Any non-canonical # is considered 0)
982 if ((sig_x
.w
[1] == 0) && (sig_x
.w
[0] == 0)) {
986 if ((sig_y
.w
[1] == 0) && (sig_y
.w
[0] == 0)) {
990 // REDUNDANT REPRESENTATIONS (CASE6)
991 if (exp_y
== exp_x
&& sig_x
.w
[1] == sig_y
.w
[1]
992 && sig_x
.w
[0] == sig_y
.w
[0]) {
993 // check if exponents are the same and significands are the same
994 if (x
.w
[1] & 0x8000000000000000ull
) { // x is negative
1001 } else if (((sig_x
.w
[1] > sig_y
.w
[1] || (sig_x
.w
[1] == sig_y
.w
[1]
1002 && sig_x
.w
[0] > sig_y
.w
[0]))
1004 || ((sig_x
.w
[1] > sig_y
.w
[1]
1005 || (sig_x
.w
[1] == sig_y
.w
[1]
1006 && sig_x
.w
[0] >= sig_y
.w
[0]))
1007 && exp_x
> exp_y
)) {
1008 // if both components are either bigger or smaller, it is clear what
1009 // needs to be done; also if the magnitudes are equal
1012 } else if (((sig_y
.w
[1] > sig_x
.w
[1] || (sig_y
.w
[1] == sig_x
.w
[1]
1013 && sig_y
.w
[0] > sig_x
.w
[0]))
1015 || ((sig_y
.w
[1] > sig_x
.w
[1]
1016 || (sig_y
.w
[1] == sig_x
.w
[1]
1017 && sig_y
.w
[0] >= sig_x
.w
[0]))
1018 && exp_y
> exp_x
)) {
1024 diff
= exp_x
- exp_y
;
1025 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1026 if (diff
> 0) { // to simplify the loop below,
1027 // if exp_x is 33 greater than exp_y, no need for compensation
1029 res
= x
; // difference cannot be greater than 10^33
1032 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
1033 __mul_128x128_to_256 (sig_n_prime256
, sig_x
, ten2k128
[diff
- 20]);
1034 // if postitive, return whichever significand is larger
1035 // (converse if negative)
1036 if (sig_n_prime256
.w
[3] == 0 && (sig_n_prime256
.w
[2] == 0)
1037 && sig_n_prime256
.w
[1] == sig_y
.w
[1]
1038 && (sig_n_prime256
.w
[0] == sig_y
.w
[0])) {
1039 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
; // if equal
1042 res
= (((sig_n_prime256
.w
[3] > 0) || sig_n_prime256
.w
[2] > 0)
1043 || (sig_n_prime256
.w
[1] > sig_y
.w
[1])
1044 || (sig_n_prime256
.w
[1] == sig_y
.w
[1]
1045 && sig_n_prime256
.w
[0] > sig_y
.w
[0])) ? x
: y
;
1048 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_x
);
1049 // if postitive, return whichever significand is larger (converse if negative)
1050 if ((sig_n_prime192
.w
[2] == 0) && sig_n_prime192
.w
[1] == sig_y
.w
[1]
1051 && (sig_n_prime192
.w
[0] == sig_y
.w
[0])) {
1052 // if equal, return positive magnitude
1053 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
1056 res
= ((sig_n_prime192
.w
[2] > 0)
1057 || (sig_n_prime192
.w
[1] > sig_y
.w
[1])
1058 || (sig_n_prime192
.w
[1] == sig_y
.w
[1]
1059 && sig_n_prime192
.w
[0] > sig_y
.w
[0])) ? x
: y
;
1062 diff
= exp_y
- exp_x
;
1063 // if exp_x is 33 less than exp_y, no need for compensation
1068 if (diff
> 19) { //128 by 128 bit multiply -> 256 bits
1069 // adjust the y significand upwards
1070 __mul_128x128_to_256 (sig_n_prime256
, sig_y
, ten2k128
[diff
- 20]);
1071 // if postitive, return whichever significand is larger
1072 // (converse if negative)
1073 if (sig_n_prime256
.w
[3] == 0 && (sig_n_prime256
.w
[2] == 0)
1074 && sig_n_prime256
.w
[1] == sig_x
.w
[1]
1075 && (sig_n_prime256
.w
[0] == sig_x
.w
[0])) {
1076 // if equal, return positive (if possible)
1077 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
1080 res
= (sig_n_prime256
.w
[3] == 0 && sig_n_prime256
.w
[2] == 0
1081 && (sig_n_prime256
.w
[1] < sig_x
.w
[1]
1082 || (sig_n_prime256
.w
[1] == sig_x
.w
[1]
1083 && sig_n_prime256
.w
[0] < sig_x
.w
[0]))) ? x
: y
;
1086 // adjust the y significand upwards
1087 __mul_64x128_to_192 (sig_n_prime192
, ten2k64
[diff
], sig_y
);
1088 // if postitive, return whichever significand is larger (converse if negative)
1089 if ((sig_n_prime192
.w
[2] == 0) && sig_n_prime192
.w
[1] == sig_x
.w
[1]
1090 && (sig_n_prime192
.w
[0] == sig_x
.w
[0])) {
1091 // if equal, return positive (if possible)
1092 res
= ((y
.w
[1] & MASK_SIGN
) == MASK_SIGN
) ? x
: y
;
1095 res
= (sig_n_prime192
.w
[2] == 0
1096 && (sig_n_prime192
.w
[1] < sig_x
.w
[1]
1097 || (sig_n_prime192
.w
[1] == sig_x
.w
[1]
1098 && sig_n_prime192
.w
[0] < sig_x
.w
[0]))) ? x
: y
;