1 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.
2 
3 This file is part of GCC.
4 
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.
9 
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.
14 
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.
18 
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/>.  */
23 
24 #include "bid_internal.h"
25 
26 /*****************************************************************************
27  *  BID64 minimum function - returns greater of two numbers
28  *****************************************************************************/
29 
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
36 };
37 
38 #if DECIMAL_CALL_BY_REFERENCE
39 void
bid64_minnum(UINT64 * pres,UINT64 * px,UINT64 * py _EXC_FLAGS_PARAM)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
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
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
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
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
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
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
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