Merge -r 127928:132243 from trunk
[official-gcc.git] / libgcc / config / libbid / bid64_minmax.c
blob1b466bc1ece553669ebbe876f31f43f2d97de0f4
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
8 version.
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
17 executable.)
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
22 for more details.
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
27 02110-1301, USA. */
29 #include "bid_internal.h"
31 /*****************************************************************************
32 * BID64 minimum function - returns greater of two numbers
33 *****************************************************************************/
35 static const UINT64 mult_factor[16] = {
36 1ull, 10ull, 100ull, 1000ull,
37 10000ull, 100000ull, 1000000ull, 10000000ull,
38 100000000ull, 1000000000ull, 10000000000ull, 100000000000ull,
39 1000000000000ull, 10000000000000ull,
40 100000000000000ull, 1000000000000000ull
43 #if DECIMAL_CALL_BY_REFERENCE
44 void
45 bid64_minnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
46 UINT64 x = *px;
47 UINT64 y = *py;
48 #else
49 UINT64
50 bid64_minnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
51 #endif
53 UINT64 res;
54 int exp_x, exp_y;
55 UINT64 sig_x, sig_y;
56 UINT128 sig_n_prime;
57 char x_is_zero = 0, y_is_zero = 0;
59 // check for non-canonical x
60 if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
61 x = x & 0xfe03ffffffffffffull; // clear G6-G12
62 if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
63 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
65 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
66 x = x & (MASK_SIGN | MASK_INF);
67 } else { // x is not special
68 // check for non-canonical values - treated as zero
69 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
70 // if the steering bits are 11, then the exponent is G[0:w+1]
71 if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
72 9999999999999999ull) {
73 // non-canonical
74 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
75 } // else canonical
76 } // else canonical
79 // check for non-canonical y
80 if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
81 y = y & 0xfe03ffffffffffffull; // clear G6-G12
82 if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
83 y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
85 } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
86 y = y & (MASK_SIGN | MASK_INF);
87 } else { // y is not special
88 // check for non-canonical values - treated as zero
89 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
90 // if the steering bits are 11, then the exponent is G[0:w+1]
91 if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
92 9999999999999999ull) {
93 // non-canonical
94 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
95 } // else canonical
96 } // else canonical
99 // NaN (CASE1)
100 if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
101 if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
102 // if x is SNAN, then return quiet (x)
103 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
104 x = x & 0xfdffffffffffffffull; // quietize x
105 res = x;
106 } else { // x is QNaN
107 if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
108 if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
109 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
111 res = x;
112 } else {
113 res = y;
116 BID_RETURN (res);
117 } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
118 if ((y & MASK_SNAN) == MASK_SNAN) {
119 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
120 y = y & 0xfdffffffffffffffull; // quietize y
121 res = y;
122 } else {
123 // will return x (which is not NaN)
124 res = x;
126 BID_RETURN (res);
128 // SIMPLE (CASE2)
129 // if all the bits are the same, these numbers are equal, return either number
130 if (x == y) {
131 res = x;
132 BID_RETURN (res);
134 // INFINITY (CASE3)
135 if ((x & MASK_INF) == MASK_INF) {
136 // if x is neg infinity, there is no way it is greater than y, return x
137 if (((x & MASK_SIGN) == MASK_SIGN)) {
138 res = x;
139 BID_RETURN (res);
141 // x is pos infinity, return y
142 else {
143 res = y;
144 BID_RETURN (res);
146 } else if ((y & MASK_INF) == MASK_INF) {
147 // x is finite, so if y is positive infinity, then x is less, return y
148 // if y is negative infinity, then x is greater, return x
149 res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
150 BID_RETURN (res);
152 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
153 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
154 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
155 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
156 } else {
157 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
158 sig_x = (x & MASK_BINARY_SIG1);
161 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
162 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
163 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
164 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
165 } else {
166 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
167 sig_y = (y & MASK_BINARY_SIG1);
170 // ZERO (CASE4)
171 // some properties:
172 // (+ZERO == -ZERO) => therefore
173 // ignore the sign, and neither number is greater
174 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
175 // ignore the exponent field
176 // (Any non-canonical # is considered 0)
177 if (sig_x == 0) {
178 x_is_zero = 1;
180 if (sig_y == 0) {
181 y_is_zero = 1;
184 if (x_is_zero && y_is_zero) {
185 // if both numbers are zero, neither is greater => return either
186 res = y;
187 BID_RETURN (res);
188 } else if (x_is_zero) {
189 // is x is zero, it is greater if Y is negative
190 res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
191 BID_RETURN (res);
192 } else if (y_is_zero) {
193 // is y is zero, X is greater if it is positive
194 res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x;;
195 BID_RETURN (res);
197 // OPPOSITE SIGN (CASE5)
198 // now, if the sign bits differ, x is greater if y is negative
199 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) {
200 res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
201 BID_RETURN (res);
203 // REDUNDANT REPRESENTATIONS (CASE6)
205 // if both components are either bigger or smaller,
206 // it is clear what needs to be done
207 if (sig_x > sig_y && exp_x >= exp_y) {
208 res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x;
209 BID_RETURN (res);
211 if (sig_x < sig_y && exp_x <= exp_y) {
212 res = ((x & MASK_SIGN) == MASK_SIGN) ? y : x;
213 BID_RETURN (res);
215 // if exp_x is 15 greater than exp_y, no need for compensation
216 if (exp_x - exp_y > 15) {
217 res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x; // difference cannot be >10^15
218 BID_RETURN (res);
220 // if exp_x is 15 less than exp_y, no need for compensation
221 if (exp_y - exp_x > 15) {
222 res = ((x & MASK_SIGN) == MASK_SIGN) ? y : x;
223 BID_RETURN (res);
225 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
226 if (exp_x > exp_y) { // to simplify the loop below,
228 // otherwise adjust the x significand upwards
229 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
230 mult_factor[exp_x - exp_y]);
231 // if postitive, return whichever significand is larger
232 // (converse if negative)
233 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
234 res = y;
235 BID_RETURN (res);
238 res = (((sig_n_prime.w[1] > 0)
239 || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) ==
240 MASK_SIGN)) ? y : x;
241 BID_RETURN (res);
243 // adjust the y significand upwards
244 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
245 mult_factor[exp_y - exp_x]);
247 // if postitive, return whichever significand is larger (converse if negative)
248 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
249 res = y;
250 BID_RETURN (res);
252 res = (((sig_n_prime.w[1] == 0)
253 && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
254 MASK_SIGN)) ? y : x;
255 BID_RETURN (res);
258 /*****************************************************************************
259 * BID64 minimum magnitude function - returns greater of two numbers
260 *****************************************************************************/
262 #if DECIMAL_CALL_BY_REFERENCE
263 void
264 bid64_minnum_mag (UINT64 * pres, UINT64 * px,
265 UINT64 * py _EXC_FLAGS_PARAM) {
266 UINT64 x = *px;
267 UINT64 y = *py;
268 #else
269 UINT64
270 bid64_minnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
271 #endif
273 UINT64 res;
274 int exp_x, exp_y;
275 UINT64 sig_x, sig_y;
276 UINT128 sig_n_prime;
278 // check for non-canonical x
279 if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
280 x = x & 0xfe03ffffffffffffull; // clear G6-G12
281 if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
282 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
284 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
285 x = x & (MASK_SIGN | MASK_INF);
286 } else { // x is not special
287 // check for non-canonical values - treated as zero
288 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
289 // if the steering bits are 11, then the exponent is G[0:w+1]
290 if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
291 9999999999999999ull) {
292 // non-canonical
293 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
294 } // else canonical
295 } // else canonical
298 // check for non-canonical y
299 if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
300 y = y & 0xfe03ffffffffffffull; // clear G6-G12
301 if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
302 y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
304 } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
305 y = y & (MASK_SIGN | MASK_INF);
306 } else { // y is not special
307 // check for non-canonical values - treated as zero
308 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
309 // if the steering bits are 11, then the exponent is G[0:w+1]
310 if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
311 9999999999999999ull) {
312 // non-canonical
313 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
314 } // else canonical
315 } // else canonical
318 // NaN (CASE1)
319 if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
320 if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
321 // if x is SNAN, then return quiet (x)
322 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
323 x = x & 0xfdffffffffffffffull; // quietize x
324 res = x;
325 } else { // x is QNaN
326 if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
327 if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
328 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
330 res = x;
331 } else {
332 res = y;
335 BID_RETURN (res);
336 } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
337 if ((y & MASK_SNAN) == MASK_SNAN) {
338 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
339 y = y & 0xfdffffffffffffffull; // quietize y
340 res = y;
341 } else {
342 // will return x (which is not NaN)
343 res = x;
345 BID_RETURN (res);
347 // SIMPLE (CASE2)
348 // if all the bits are the same, these numbers are equal, return either number
349 if (x == y) {
350 res = x;
351 BID_RETURN (res);
353 // INFINITY (CASE3)
354 if ((x & MASK_INF) == MASK_INF) {
355 // x is infinity, its magnitude is greater than or equal to y
356 // return x only if y is infinity and x is negative
357 res = ((x & MASK_SIGN) == MASK_SIGN
358 && (y & MASK_INF) == MASK_INF) ? x : y;
359 BID_RETURN (res);
360 } else if ((y & MASK_INF) == MASK_INF) {
361 // y is infinity, then it must be greater in magnitude, return x
362 res = x;
363 BID_RETURN (res);
365 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
366 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
367 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
368 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
369 } else {
370 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
371 sig_x = (x & MASK_BINARY_SIG1);
374 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
375 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
376 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
377 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
378 } else {
379 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
380 sig_y = (y & MASK_BINARY_SIG1);
383 // ZERO (CASE4)
384 // some properties:
385 // (+ZERO == -ZERO) => therefore
386 // ignore the sign, and neither number is greater
387 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
388 // ignore the exponent field
389 // (Any non-canonical # is considered 0)
390 if (sig_x == 0) {
391 res = x; // x_is_zero, its magnitude must be smaller than y
392 BID_RETURN (res);
394 if (sig_y == 0) {
395 res = y; // y_is_zero, its magnitude must be smaller than x
396 BID_RETURN (res);
398 // REDUNDANT REPRESENTATIONS (CASE6)
399 // if both components are either bigger or smaller,
400 // it is clear what needs to be done
401 if (sig_x > sig_y && exp_x >= exp_y) {
402 res = y;
403 BID_RETURN (res);
405 if (sig_x < sig_y && exp_x <= exp_y) {
406 res = x;
407 BID_RETURN (res);
409 // if exp_x is 15 greater than exp_y, no need for compensation
410 if (exp_x - exp_y > 15) {
411 res = y; // difference cannot be greater than 10^15
412 BID_RETURN (res);
414 // if exp_x is 15 less than exp_y, no need for compensation
415 if (exp_y - exp_x > 15) {
416 res = x;
417 BID_RETURN (res);
419 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
420 if (exp_x > exp_y) { // to simplify the loop below,
421 // otherwise adjust the x significand upwards
422 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
423 mult_factor[exp_x - exp_y]);
424 // now, sig_n_prime has: sig_x * 10^(exp_x-exp_y), this is
425 // the compensated signif.
426 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
427 // two numbers are equal, return minNum(x,y)
428 res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
429 BID_RETURN (res);
431 // now, if compensated_x (sig_n_prime) is greater than y, return y,
432 // otherwise return x
433 res = ((sig_n_prime.w[1] != 0) || sig_n_prime.w[0] > sig_y) ? y : x;
434 BID_RETURN (res);
436 // exp_y must be greater than exp_x, thus adjust the y significand upwards
437 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
438 mult_factor[exp_y - exp_x]);
440 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
441 res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
442 // two numbers are equal, return either
443 BID_RETURN (res);
446 res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? y : x;
447 BID_RETURN (res);
450 /*****************************************************************************
451 * BID64 maximum function - returns greater of two numbers
452 *****************************************************************************/
454 #if DECIMAL_CALL_BY_REFERENCE
455 void
456 bid64_maxnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
457 UINT64 x = *px;
458 UINT64 y = *py;
459 #else
460 UINT64
461 bid64_maxnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
462 #endif
464 UINT64 res;
465 int exp_x, exp_y;
466 UINT64 sig_x, sig_y;
467 UINT128 sig_n_prime;
468 char x_is_zero = 0, y_is_zero = 0;
470 // check for non-canonical x
471 if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
472 x = x & 0xfe03ffffffffffffull; // clear G6-G12
473 if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
474 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
476 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
477 x = x & (MASK_SIGN | MASK_INF);
478 } else { // x is not special
479 // check for non-canonical values - treated as zero
480 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
481 // if the steering bits are 11, then the exponent is G[0:w+1]
482 if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
483 9999999999999999ull) {
484 // non-canonical
485 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
486 } // else canonical
487 } // else canonical
490 // check for non-canonical y
491 if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
492 y = y & 0xfe03ffffffffffffull; // clear G6-G12
493 if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
494 y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
496 } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
497 y = y & (MASK_SIGN | MASK_INF);
498 } else { // y is not special
499 // check for non-canonical values - treated as zero
500 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
501 // if the steering bits are 11, then the exponent is G[0:w+1]
502 if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
503 9999999999999999ull) {
504 // non-canonical
505 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
506 } // else canonical
507 } // else canonical
510 // NaN (CASE1)
511 if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
512 if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
513 // if x is SNAN, then return quiet (x)
514 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
515 x = x & 0xfdffffffffffffffull; // quietize x
516 res = x;
517 } else { // x is QNaN
518 if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
519 if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
520 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
522 res = x;
523 } else {
524 res = y;
527 BID_RETURN (res);
528 } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
529 if ((y & MASK_SNAN) == MASK_SNAN) {
530 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
531 y = y & 0xfdffffffffffffffull; // quietize y
532 res = y;
533 } else {
534 // will return x (which is not NaN)
535 res = x;
537 BID_RETURN (res);
539 // SIMPLE (CASE2)
540 // if all the bits are the same, these numbers are equal (not Greater).
541 if (x == y) {
542 res = x;
543 BID_RETURN (res);
545 // INFINITY (CASE3)
546 if ((x & MASK_INF) == MASK_INF) {
547 // if x is neg infinity, there is no way it is greater than y, return y
548 // x is pos infinity, it is greater, unless y is positive infinity =>
549 // return y!=pos_infinity
550 if (((x & MASK_SIGN) == MASK_SIGN)) {
551 res = y;
552 BID_RETURN (res);
553 } else {
554 res = (((y & MASK_INF) != MASK_INF)
555 || ((y & MASK_SIGN) == MASK_SIGN)) ? x : y;
556 BID_RETURN (res);
558 } else if ((y & MASK_INF) == MASK_INF) {
559 // x is finite, so if y is positive infinity, then x is less, return y
560 // if y is negative infinity, then x is greater, return x
561 res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
562 BID_RETURN (res);
564 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
565 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
566 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
567 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
568 } else {
569 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
570 sig_x = (x & MASK_BINARY_SIG1);
573 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
574 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
575 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
576 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
577 } else {
578 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
579 sig_y = (y & MASK_BINARY_SIG1);
582 // ZERO (CASE4)
583 // some properties:
584 // (+ZERO == -ZERO) => therefore
585 // ignore the sign, and neither number is greater
586 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
587 // ignore the exponent field
588 // (Any non-canonical # is considered 0)
589 if (sig_x == 0) {
590 x_is_zero = 1;
592 if (sig_y == 0) {
593 y_is_zero = 1;
596 if (x_is_zero && y_is_zero) {
597 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
598 res = y;
599 BID_RETURN (res);
600 } else if (x_is_zero) {
601 // is x is zero, it is greater if Y is negative
602 res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
603 BID_RETURN (res);
604 } else if (y_is_zero) {
605 // is y is zero, X is greater if it is positive
606 res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;;
607 BID_RETURN (res);
609 // OPPOSITE SIGN (CASE5)
610 // now, if the sign bits differ, x is greater if y is negative
611 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) {
612 res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
613 BID_RETURN (res);
615 // REDUNDANT REPRESENTATIONS (CASE6)
617 // if both components are either bigger or smaller,
618 // it is clear what needs to be done
619 if (sig_x > sig_y && exp_x >= exp_y) {
620 res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;
621 BID_RETURN (res);
623 if (sig_x < sig_y && exp_x <= exp_y) {
624 res = ((x & MASK_SIGN) == MASK_SIGN) ? x : y;
625 BID_RETURN (res);
627 // if exp_x is 15 greater than exp_y, no need for compensation
628 if (exp_x - exp_y > 15) {
629 res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;
630 // difference cannot be > 10^15
631 BID_RETURN (res);
633 // if exp_x is 15 less than exp_y, no need for compensation
634 if (exp_y - exp_x > 15) {
635 res = ((x & MASK_SIGN) == MASK_SIGN) ? x : y;
636 BID_RETURN (res);
638 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
639 if (exp_x > exp_y) { // to simplify the loop below,
640 // otherwise adjust the x significand upwards
641 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
642 mult_factor[exp_x - exp_y]);
643 // if postitive, return whichever significand is larger
644 // (converse if negative)
645 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
646 res = y;
647 BID_RETURN (res);
649 res = (((sig_n_prime.w[1] > 0)
650 || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) ==
651 MASK_SIGN)) ? x : y;
652 BID_RETURN (res);
654 // adjust the y significand upwards
655 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
656 mult_factor[exp_y - exp_x]);
658 // if postitive, return whichever significand is larger (converse if negative)
659 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
660 res = y;
661 BID_RETURN (res);
663 res = (((sig_n_prime.w[1] == 0)
664 && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
665 MASK_SIGN)) ? x : y;
666 BID_RETURN (res);
669 /*****************************************************************************
670 * BID64 maximum magnitude function - returns greater of two numbers
671 *****************************************************************************/
673 #if DECIMAL_CALL_BY_REFERENCE
674 void
675 bid64_maxnum_mag (UINT64 * pres, UINT64 * px,
676 UINT64 * py _EXC_FLAGS_PARAM) {
677 UINT64 x = *px;
678 UINT64 y = *py;
679 #else
680 UINT64
681 bid64_maxnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
682 #endif
684 UINT64 res;
685 int exp_x, exp_y;
686 UINT64 sig_x, sig_y;
687 UINT128 sig_n_prime;
689 // check for non-canonical x
690 if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
691 x = x & 0xfe03ffffffffffffull; // clear G6-G12
692 if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
693 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
695 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
696 x = x & (MASK_SIGN | MASK_INF);
697 } else { // x is not special
698 // check for non-canonical values - treated as zero
699 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
700 // if the steering bits are 11, then the exponent is G[0:w+1]
701 if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
702 9999999999999999ull) {
703 // non-canonical
704 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
705 } // else canonical
706 } // else canonical
709 // check for non-canonical y
710 if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
711 y = y & 0xfe03ffffffffffffull; // clear G6-G12
712 if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
713 y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
715 } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
716 y = y & (MASK_SIGN | MASK_INF);
717 } else { // y is not special
718 // check for non-canonical values - treated as zero
719 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
720 // if the steering bits are 11, then the exponent is G[0:w+1]
721 if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
722 9999999999999999ull) {
723 // non-canonical
724 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
725 } // else canonical
726 } // else canonical
729 // NaN (CASE1)
730 if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
731 if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
732 // if x is SNAN, then return quiet (x)
733 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
734 x = x & 0xfdffffffffffffffull; // quietize x
735 res = x;
736 } else { // x is QNaN
737 if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
738 if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
739 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
741 res = x;
742 } else {
743 res = y;
746 BID_RETURN (res);
747 } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
748 if ((y & MASK_SNAN) == MASK_SNAN) {
749 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
750 y = y & 0xfdffffffffffffffull; // quietize y
751 res = y;
752 } else {
753 // will return x (which is not NaN)
754 res = x;
756 BID_RETURN (res);
758 // SIMPLE (CASE2)
759 // if all the bits are the same, these numbers are equal, return either number
760 if (x == y) {
761 res = x;
762 BID_RETURN (res);
764 // INFINITY (CASE3)
765 if ((x & MASK_INF) == MASK_INF) {
766 // x is infinity, its magnitude is greater than or equal to y
767 // return y as long as x isn't negative infinity
768 res = ((x & MASK_SIGN) == MASK_SIGN
769 && (y & MASK_INF) == MASK_INF) ? y : x;
770 BID_RETURN (res);
771 } else if ((y & MASK_INF) == MASK_INF) {
772 // y is infinity, then it must be greater in magnitude
773 res = y;
774 BID_RETURN (res);
776 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
777 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
778 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
779 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
780 } else {
781 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
782 sig_x = (x & MASK_BINARY_SIG1);
785 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
786 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
787 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
788 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
789 } else {
790 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
791 sig_y = (y & MASK_BINARY_SIG1);
794 // ZERO (CASE4)
795 // some properties:
796 // (+ZERO == -ZERO) => therefore
797 // ignore the sign, and neither number is greater
798 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
799 // ignore the exponent field
800 // (Any non-canonical # is considered 0)
801 if (sig_x == 0) {
802 res = y; // x_is_zero, its magnitude must be smaller than y
803 BID_RETURN (res);
805 if (sig_y == 0) {
806 res = x; // y_is_zero, its magnitude must be smaller than x
807 BID_RETURN (res);
809 // REDUNDANT REPRESENTATIONS (CASE6)
810 // if both components are either bigger or smaller,
811 // it is clear what needs to be done
812 if (sig_x > sig_y && exp_x >= exp_y) {
813 res = x;
814 BID_RETURN (res);
816 if (sig_x < sig_y && exp_x <= exp_y) {
817 res = y;
818 BID_RETURN (res);
820 // if exp_x is 15 greater than exp_y, no need for compensation
821 if (exp_x - exp_y > 15) {
822 res = x; // difference cannot be greater than 10^15
823 BID_RETURN (res);
825 // if exp_x is 15 less than exp_y, no need for compensation
826 if (exp_y - exp_x > 15) {
827 res = y;
828 BID_RETURN (res);
830 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
831 if (exp_x > exp_y) { // to simplify the loop below,
832 // otherwise adjust the x significand upwards
833 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
834 mult_factor[exp_x - exp_y]);
835 // now, sig_n_prime has: sig_x * 10^(exp_x-exp_y),
836 // this is the compensated signif.
837 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
838 // two numbers are equal, return maxNum(x,y)
839 res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
840 BID_RETURN (res);
842 // now, if compensated_x (sig_n_prime) is greater than y return y,
843 // otherwise return x
844 res = ((sig_n_prime.w[1] != 0) || sig_n_prime.w[0] > sig_y) ? x : y;
845 BID_RETURN (res);
847 // exp_y must be greater than exp_x, thus adjust the y significand upwards
848 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
849 mult_factor[exp_y - exp_x]);
851 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
852 res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
853 // two numbers are equal, return either
854 BID_RETURN (res);
857 res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? x : y;
858 BID_RETURN (res);