tree-optimization/117484 - issue with SLP discovery of permuted .MASK_LOAD
[official-gcc.git] / libgcc / config / libbid / bid64_minmax.c
blob5f609da0b9ebfd36dc1a584528543f214219d958
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
8 version.
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
13 for more details.
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
39 void
40 bid64_minnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
41 UINT64 x = *px;
42 UINT64 y = *py;
43 #else
44 UINT64
45 bid64_minnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
46 #endif
48 UINT64 res;
49 int exp_x, exp_y;
50 UINT64 sig_x, sig_y;
51 UINT128 sig_n_prime;
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) {
68 // non-canonical
69 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
70 } // else canonical
71 } // else canonical
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) {
88 // non-canonical
89 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
90 } // else canonical
91 } // else canonical
94 // NaN (CASE1)
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
100 res = 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
106 res = x;
107 } else {
108 res = y;
111 BID_RETURN (res);
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
116 res = y;
117 } else {
118 // will return x (which is not NaN)
119 res = x;
121 BID_RETURN (res);
123 // SIMPLE (CASE2)
124 // if all the bits are the same, these numbers are equal, return either number
125 if (x == y) {
126 res = x;
127 BID_RETURN (res);
129 // INFINITY (CASE3)
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)) {
133 res = x;
134 BID_RETURN (res);
136 // x is pos infinity, return y
137 else {
138 res = y;
139 BID_RETURN (res);
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;
145 BID_RETURN (res);
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;
151 } else {
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;
160 } else {
161 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
162 sig_y = (y & MASK_BINARY_SIG1);
165 // ZERO (CASE4)
166 // some properties:
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)
172 if (sig_x == 0) {
173 x_is_zero = 1;
175 if (sig_y == 0) {
176 y_is_zero = 1;
179 if (x_is_zero && y_is_zero) {
180 // if both numbers are zero, neither is greater => return either
181 res = y;
182 BID_RETURN (res);
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;
186 BID_RETURN (res);
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;;
190 BID_RETURN (res);
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;
196 BID_RETURN (res);
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;
204 BID_RETURN (res);
206 if (sig_x < sig_y && exp_x <= exp_y) {
207 res = ((x & MASK_SIGN) == MASK_SIGN) ? y : x;
208 BID_RETURN (res);
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
213 BID_RETURN (res);
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;
218 BID_RETURN (res);
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)) {
229 res = y;
230 BID_RETURN (res);
233 res = (((sig_n_prime.w[1] > 0)
234 || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) ==
235 MASK_SIGN)) ? y : x;
236 BID_RETURN (res);
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)) {
244 res = y;
245 BID_RETURN (res);
247 res = (((sig_n_prime.w[1] == 0)
248 && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
249 MASK_SIGN)) ? y : x;
250 BID_RETURN (res);
253 /*****************************************************************************
254 * BID64 minimum magnitude function - returns greater of two numbers
255 *****************************************************************************/
257 #if DECIMAL_CALL_BY_REFERENCE
258 void
259 bid64_minnum_mag (UINT64 * pres, UINT64 * px,
260 UINT64 * py _EXC_FLAGS_PARAM) {
261 UINT64 x = *px;
262 UINT64 y = *py;
263 #else
264 UINT64
265 bid64_minnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
266 #endif
268 UINT64 res;
269 int exp_x, exp_y;
270 UINT64 sig_x, sig_y;
271 UINT128 sig_n_prime;
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) {
287 // non-canonical
288 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
289 } // else canonical
290 } // else canonical
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) {
307 // non-canonical
308 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
309 } // else canonical
310 } // else canonical
313 // NaN (CASE1)
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
319 res = 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
325 res = x;
326 } else {
327 res = y;
330 BID_RETURN (res);
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
335 res = y;
336 } else {
337 // will return x (which is not NaN)
338 res = x;
340 BID_RETURN (res);
342 // SIMPLE (CASE2)
343 // if all the bits are the same, these numbers are equal, return either number
344 if (x == y) {
345 res = x;
346 BID_RETURN (res);
348 // INFINITY (CASE3)
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;
354 BID_RETURN (res);
355 } else if ((y & MASK_INF) == MASK_INF) {
356 // y is infinity, then it must be greater in magnitude, return x
357 res = x;
358 BID_RETURN (res);
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;
364 } else {
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;
373 } else {
374 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
375 sig_y = (y & MASK_BINARY_SIG1);
378 // ZERO (CASE4)
379 // some properties:
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)
385 if (sig_x == 0) {
386 res = x; // x_is_zero, its magnitude must be smaller than y
387 BID_RETURN (res);
389 if (sig_y == 0) {
390 res = y; // y_is_zero, its magnitude must be smaller than x
391 BID_RETURN (res);
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) {
397 res = y;
398 BID_RETURN (res);
400 if (sig_x < sig_y && exp_x <= exp_y) {
401 res = x;
402 BID_RETURN (res);
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
407 BID_RETURN (res);
409 // if exp_x is 15 less than exp_y, no need for compensation
410 if (exp_y - exp_x > 15) {
411 res = x;
412 BID_RETURN (res);
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;
424 BID_RETURN (res);
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;
429 BID_RETURN (res);
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
438 BID_RETURN (res);
441 res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? y : x;
442 BID_RETURN (res);
445 /*****************************************************************************
446 * BID64 maximum function - returns greater of two numbers
447 *****************************************************************************/
449 #if DECIMAL_CALL_BY_REFERENCE
450 void
451 bid64_maxnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
452 UINT64 x = *px;
453 UINT64 y = *py;
454 #else
455 UINT64
456 bid64_maxnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
457 #endif
459 UINT64 res;
460 int exp_x, exp_y;
461 UINT64 sig_x, sig_y;
462 UINT128 sig_n_prime;
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) {
479 // non-canonical
480 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
481 } // else canonical
482 } // else canonical
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) {
499 // non-canonical
500 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
501 } // else canonical
502 } // else canonical
505 // NaN (CASE1)
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
511 res = 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
517 res = x;
518 } else {
519 res = y;
522 BID_RETURN (res);
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
527 res = y;
528 } else {
529 // will return x (which is not NaN)
530 res = x;
532 BID_RETURN (res);
534 // SIMPLE (CASE2)
535 // if all the bits are the same, these numbers are equal (not Greater).
536 if (x == y) {
537 res = x;
538 BID_RETURN (res);
540 // INFINITY (CASE3)
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)) {
546 res = y;
547 BID_RETURN (res);
548 } else {
549 res = (((y & MASK_INF) != MASK_INF)
550 || ((y & MASK_SIGN) == MASK_SIGN)) ? x : y;
551 BID_RETURN (res);
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;
557 BID_RETURN (res);
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;
563 } else {
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;
572 } else {
573 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
574 sig_y = (y & MASK_BINARY_SIG1);
577 // ZERO (CASE4)
578 // some properties:
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)
584 if (sig_x == 0) {
585 x_is_zero = 1;
587 if (sig_y == 0) {
588 y_is_zero = 1;
591 if (x_is_zero && y_is_zero) {
592 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
593 res = y;
594 BID_RETURN (res);
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;
598 BID_RETURN (res);
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;;
602 BID_RETURN (res);
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;
608 BID_RETURN (res);
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;
616 BID_RETURN (res);
618 if (sig_x < sig_y && exp_x <= exp_y) {
619 res = ((x & MASK_SIGN) == MASK_SIGN) ? x : y;
620 BID_RETURN (res);
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
626 BID_RETURN (res);
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;
631 BID_RETURN (res);
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)) {
641 res = y;
642 BID_RETURN (res);
644 res = (((sig_n_prime.w[1] > 0)
645 || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) ==
646 MASK_SIGN)) ? x : y;
647 BID_RETURN (res);
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)) {
655 res = y;
656 BID_RETURN (res);
658 res = (((sig_n_prime.w[1] == 0)
659 && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
660 MASK_SIGN)) ? x : y;
661 BID_RETURN (res);
664 /*****************************************************************************
665 * BID64 maximum magnitude function - returns greater of two numbers
666 *****************************************************************************/
668 #if DECIMAL_CALL_BY_REFERENCE
669 void
670 bid64_maxnum_mag (UINT64 * pres, UINT64 * px,
671 UINT64 * py _EXC_FLAGS_PARAM) {
672 UINT64 x = *px;
673 UINT64 y = *py;
674 #else
675 UINT64
676 bid64_maxnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
677 #endif
679 UINT64 res;
680 int exp_x, exp_y;
681 UINT64 sig_x, sig_y;
682 UINT128 sig_n_prime;
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) {
698 // non-canonical
699 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
700 } // else canonical
701 } // else canonical
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) {
718 // non-canonical
719 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
720 } // else canonical
721 } // else canonical
724 // NaN (CASE1)
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
730 res = 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
736 res = x;
737 } else {
738 res = y;
741 BID_RETURN (res);
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
746 res = y;
747 } else {
748 // will return x (which is not NaN)
749 res = x;
751 BID_RETURN (res);
753 // SIMPLE (CASE2)
754 // if all the bits are the same, these numbers are equal, return either number
755 if (x == y) {
756 res = x;
757 BID_RETURN (res);
759 // INFINITY (CASE3)
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;
765 BID_RETURN (res);
766 } else if ((y & MASK_INF) == MASK_INF) {
767 // y is infinity, then it must be greater in magnitude
768 res = y;
769 BID_RETURN (res);
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;
775 } else {
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;
784 } else {
785 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
786 sig_y = (y & MASK_BINARY_SIG1);
789 // ZERO (CASE4)
790 // some properties:
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)
796 if (sig_x == 0) {
797 res = y; // x_is_zero, its magnitude must be smaller than y
798 BID_RETURN (res);
800 if (sig_y == 0) {
801 res = x; // y_is_zero, its magnitude must be smaller than x
802 BID_RETURN (res);
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) {
808 res = x;
809 BID_RETURN (res);
811 if (sig_x < sig_y && exp_x <= exp_y) {
812 res = y;
813 BID_RETURN (res);
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
818 BID_RETURN (res);
820 // if exp_x is 15 less than exp_y, no need for compensation
821 if (exp_y - exp_x > 15) {
822 res = y;
823 BID_RETURN (res);
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;
835 BID_RETURN (res);
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;
840 BID_RETURN (res);
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
849 BID_RETURN (res);
852 res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? x : y;
853 BID_RETURN (res);