1/* Copyright (C) 2007-2015 Free Software Foundation, Inc.
2
3This file is part of GCC.
4
5GCC is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License as published by the Free
7Software Foundation; either version 3, or (at your option) any later
8version.
9
10GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11WARRANTY; without even the implied warranty of MERCHANTABILITY or
12FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13for more details.
14
15Under Section 7 of GPL version 3, you are granted additional
16permissions described in the GCC Runtime Library Exception, version
173.1, as published by the Free Software Foundation.
18
19You should have received a copy of the GNU General Public License and
20a copy of the GCC Runtime Library Exception along with this program;
21see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
22<http://www.gnu.org/licenses/>.  */
23
24#include "bid_internal.h"
25
26/*****************************************************************************
27 *  BID64 minimum function - returns greater of two numbers
28 *****************************************************************************/
29
30static 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
36};
37
38#if DECIMAL_CALL_BY_REFERENCE
39void
40bid64_minnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
41  UINT64 x = *px;
42  UINT64 y = *py;
43#else
44UINT64
45bid64_minnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
46#endif
47
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;
53
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
59    }
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
72  }
73
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
79    }
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
92  }
93
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
105	}
106	res = x;
107      } else {
108	res = y;
109      }
110    }
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;
120    }
121    BID_RETURN (res);
122  }
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);
128  }
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);
135    }
136    // x is pos infinity, return y
137    else {
138      res = y;
139      BID_RETURN (res);
140    }
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);
146  }
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);
154  }
155
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);
163  }
164
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;
174  }
175  if (sig_y == 0) {
176    y_is_zero = 1;
177  }
178
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);
191  }
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);
197  }
198  // REDUNDANT REPRESENTATIONS (CASE6)
199
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);
205  }
206  if (sig_x < sig_y && exp_x <= exp_y) {
207    res = ((x & MASK_SIGN) == MASK_SIGN) ? y : x;
208    BID_RETURN (res);
209  }
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);
214  }
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);
219  }
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,
222
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);
231    }
232
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);
237  }
238  // adjust the y significand upwards
239  __mul_64x64_to_128MACH (sig_n_prime, sig_y,
240			  mult_factor[exp_y - exp_x]);
241
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);
246  }
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);
251}
252
253/*****************************************************************************
254 *  BID64 minimum magnitude function - returns greater of two numbers
255 *****************************************************************************/
256
257#if DECIMAL_CALL_BY_REFERENCE
258void
259bid64_minnum_mag (UINT64 * pres, UINT64 * px,
260		  UINT64 * py _EXC_FLAGS_PARAM) {
261  UINT64 x = *px;
262  UINT64 y = *py;
263#else
264UINT64
265bid64_minnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
266#endif
267
268  UINT64 res;
269  int exp_x, exp_y;
270  UINT64 sig_x, sig_y;
271  UINT128 sig_n_prime;
272
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
278    }
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
291  }
292
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
298    }
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
311  }
312
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
324	}
325	res = x;
326      } else {
327	res = y;
328      }
329    }
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;
339    }
340    BID_RETURN (res);
341  }
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);
347  }
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);
359  }
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);
367  }
368
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);
376  }
377
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);
388  }
389  if (sig_y == 0) {
390    res = y;	// y_is_zero, its magnitude must be smaller than x
391    BID_RETURN (res);
392  }
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);
399  }
400  if (sig_x < sig_y && exp_x <= exp_y) {
401    res = x;
402    BID_RETURN (res);
403  }
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);
408  }
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);
413  }
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);
425    }
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);
430  }
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]);
434
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);
439  }
440
441  res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? y : x;
442  BID_RETURN (res);
443}
444
445/*****************************************************************************
446 *  BID64 maximum function - returns greater of two numbers
447 *****************************************************************************/
448
449#if DECIMAL_CALL_BY_REFERENCE
450void
451bid64_maxnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
452  UINT64 x = *px;
453  UINT64 y = *py;
454#else
455UINT64
456bid64_maxnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
457#endif
458
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;
464
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
470    }
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
483  }
484
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
490    }
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
503  }
504
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
516	}
517	res = x;
518      } else {
519	res = y;
520      }
521    }
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;
531    }
532    BID_RETURN (res);
533  }
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);
539  }
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);
552    }
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);
558  }
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);
566  }
567
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);
575  }
576
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;
586  }
587  if (sig_y == 0) {
588    y_is_zero = 1;
589  }
590
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);
603  }
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);
609  }
610  // REDUNDANT REPRESENTATIONS (CASE6)
611
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);
617  }
618  if (sig_x < sig_y && exp_x <= exp_y) {
619    res = ((x & MASK_SIGN) == MASK_SIGN) ? x : y;
620    BID_RETURN (res);
621  }
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);
627  }
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);
632  }
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);
643    }
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);
648  }
649  // adjust the y significand upwards
650  __mul_64x64_to_128MACH (sig_n_prime, sig_y,
651			  mult_factor[exp_y - exp_x]);
652
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);
657  }
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);
662}
663
664/*****************************************************************************
665 *  BID64 maximum magnitude function - returns greater of two numbers
666 *****************************************************************************/
667
668#if DECIMAL_CALL_BY_REFERENCE
669void
670bid64_maxnum_mag (UINT64 * pres, UINT64 * px,
671		  UINT64 * py _EXC_FLAGS_PARAM) {
672  UINT64 x = *px;
673  UINT64 y = *py;
674#else
675UINT64
676bid64_maxnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
677#endif
678
679  UINT64 res;
680  int exp_x, exp_y;
681  UINT64 sig_x, sig_y;
682  UINT128 sig_n_prime;
683
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
689    }
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
702  }
703
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
709    }
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
722  }
723
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
735	}
736	res = x;
737      } else {
738	res = y;
739      }
740    }
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;
750    }
751    BID_RETURN (res);
752  }
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);
758  }
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);
770  }
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);
778  }
779
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);
787  }
788
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);
799  }
800  if (sig_y == 0) {
801    res = x;	// y_is_zero, its magnitude must be smaller than x
802    BID_RETURN (res);
803  }
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);
810  }
811  if (sig_x < sig_y && exp_x <= exp_y) {
812    res = y;
813    BID_RETURN (res);
814  }
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);
819  }
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);
824  }
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);
836    }
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);
841  }
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]);
845
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);
850  }
851
852  res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? x : y;
853  BID_RETURN (res);
854}
855