1 /* Copyright (C) 2007-2020 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 #define BID_128RES
25 #include "bid_internal.h"
26 
27 /*****************************************************************************
28  *  BID128 minimum number
29  *****************************************************************************/
30 
31 #if DECIMAL_CALL_BY_REFERENCE
32 void
bid128_minnum(UINT128 * pres,UINT128 * px,UINT128 * py _EXC_FLAGS_PARAM)33 bid128_minnum (UINT128 * pres, UINT128 * px,
34 	       UINT128 * py _EXC_FLAGS_PARAM) {
35   UINT128 x = *px;
36   UINT128 y = *py;
37 #else
38 UINT128
39 bid128_minnum (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
40 #endif
41 
42   UINT128 res;
43   int exp_x, exp_y;
44   int diff;
45   UINT128 sig_x, sig_y;
46   UINT192 sig_n_prime192;
47   UINT256 sig_n_prime256;
48   char x_is_zero = 0, y_is_zero = 0;
49 
50   BID_SWAP128 (x);
51   BID_SWAP128 (y);
52 
53   // check for non-canonical x
54   if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
55     x.w[1] = x.w[1] & 0xfe003fffffffffffull;	// clear out G[6]-G[16]
56     // check for non-canonical NaN payload
57     if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
58 	(((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
59 	 (x.w[0] > 0x38c15b09ffffffffull))) {
60       x.w[1] = x.w[1] & 0xffffc00000000000ull;
61       x.w[0] = 0x0ull;
62     }
63   } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) {	// x = inf
64     x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
65     x.w[0] = 0x0ull;
66   } else {	// x is not special
67     // check for non-canonical values - treated as zero
68     if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {	// G0_G1=11
69       // non-canonical
70       x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
71       x.w[0] = 0x0ull;
72     } else {	// G0_G1 != 11
73       if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
74 	  ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
75 	   && x.w[0] > 0x378d8e63ffffffffull)) {
76 	// x is non-canonical if coefficient is larger than 10^34 -1
77 	x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
78 	x.w[0] = 0x0ull;
79       } else {	// canonical
80 	;
81       }
82     }
83   }
84   // check for non-canonical y
85   if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NAN
86     y.w[1] = y.w[1] & 0xfe003fffffffffffull;	// clear out G[6]-G[16]
87     // check for non-canonical NaN payload
88     if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
89 	(((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
90 	 (y.w[0] > 0x38c15b09ffffffffull))) {
91       y.w[1] = y.w[1] & 0xffffc00000000000ull;
92       y.w[0] = 0x0ull;
93     }
94   } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) {	// y = inf
95     y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
96     y.w[0] = 0x0ull;
97   } else {	// y is not special
98     // check for non-canonical values - treated as zero
99     if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {	// G0_G1=11
100       // non-canonical
101       y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
102       y.w[0] = 0x0ull;
103     } else {	// G0_G1 != 11
104       if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
105 	  ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
106 	   && y.w[0] > 0x378d8e63ffffffffull)) {
107 	// y is non-canonical if coefficient is larger than 10^34 -1
108 	y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
109 	y.w[0] = 0x0ull;
110       } else {	// canonical
111 	;
112       }
113     }
114   }
115 
116   // NaN (CASE1)
117   if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
118     if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNaN
119       // if x is SNAN, then return quiet (x)
120       *pfpsf |= INVALID_EXCEPTION;	// set exception if SNaN
121       x.w[1] = x.w[1] & 0xfdffffffffffffffull;	// quietize x
122       res = x;
123     } else {	// x is QNaN
124       if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NAN
125 	if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {	// y is SNAN
126 	  *pfpsf |= INVALID_EXCEPTION;	// set invalid flag
127 	}
128 	res = x;
129       } else {
130 	res = y;
131       }
132     }
133     BID_RETURN (res);
134   } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NaN, but x is not
135     if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
136       *pfpsf |= INVALID_EXCEPTION;	// set exception if SNaN
137       y.w[1] = y.w[1] & 0xfdffffffffffffffull;	// quietize y
138       res = y;
139     } else {
140       // will return x (which is not NaN)
141       res = x;
142     }
143     BID_RETURN (res);
144   }
145   // SIMPLE (CASE2)
146   // if all the bits are the same, these numbers are equal (not Greater).
147   if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
148     res = x;
149     BID_RETURN (res);
150   }
151   // INFINITY (CASE3)
152   if ((x.w[1] & MASK_INF) == MASK_INF) {
153     // if x is neg infinity, there is no way it is greater than y, return 0
154     res = (((x.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
155     BID_RETURN (res);
156   } else if ((y.w[1] & MASK_INF) == MASK_INF) {
157     // x is finite, so if y is positive infinity, then x is less, return 0
158     //                 if y is negative infinity, then x is greater, return 1
159     res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
160     BID_RETURN (res);
161   }
162   // CONVERT X
163   sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
164   sig_x.w[0] = x.w[0];
165   exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
166 
167   // CONVERT Y
168   exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
169   sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
170   sig_y.w[0] = y.w[0];
171 
172   // ZERO (CASE4)
173   // some properties:
174   //    (+ZERO == -ZERO) => therefore ignore the sign
175   //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B => ignore the exponent
176   //    field
177   //    (Any non-canonical # is considered 0)
178   if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
179     x_is_zero = 1;
180   }
181   if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
182     y_is_zero = 1;
183   }
184 
185   if (x_is_zero && y_is_zero) {
186     // if both numbers are zero, neither is greater => return either number
187     res = x;
188     BID_RETURN (res);
189   } else if (x_is_zero) {
190     // is x is zero, it is greater if Y is negative
191     res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
192     BID_RETURN (res);
193   } else if (y_is_zero) {
194     // is y is zero, X is greater if it is positive
195     res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
196     BID_RETURN (res);
197   }
198   // OPPOSITE SIGN (CASE5)
199   // now, if the sign bits differ, x is greater if y is negative
200   if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
201     res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
202     BID_RETURN (res);
203   }
204   // REDUNDANT REPRESENTATIONS (CASE6)
205   // if exponents are the same, then we have a simple comparison of
206   //    the significands
207   if (exp_y == exp_x) {
208     res = (((sig_x.w[1] > sig_y.w[1])
209 	    || (sig_x.w[1] == sig_y.w[1]
210 		&& sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
211 						 MASK_SIGN)) ? y : x;
212     BID_RETURN (res);
213   }
214   // if both components are either bigger or smaller, it is clear what
215   //    needs to be done
216   if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0]
217       && exp_x > exp_y) {
218     res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
219     BID_RETURN (res);
220   }
221   if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
222       && exp_x < exp_y) {
223     res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
224     BID_RETURN (res);
225   }
226 
227   diff = exp_x - exp_y;
228 
229   // if |exp_x - exp_y| < 33, it comes down to the compensated significand
230   if (diff > 0) {	// to simplify the loop below,
231     // if exp_x is 33 greater than exp_y, no need for compensation
232     if (diff > 33) {
233       // difference cannot be greater than 10^33
234       res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
235       BID_RETURN (res);
236     }
237     if (diff > 19) {	//128 by 128 bit multiply -> 256 bits
238       __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
239       // if postitive, return whichever significand is larger
240       // (converse if negative)
241       res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
242 	      || (sig_n_prime256.w[1] > sig_y.w[1])
243 	      || (sig_n_prime256.w[1] == sig_y.w[1]
244 		  && sig_n_prime256.w[0] >
245 		  sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) ==
246 				  MASK_SIGN)) ? y : x;
247       BID_RETURN (res);
248     }
249     __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
250     // if postitive, return whichever significand is larger
251     // (converse if negative)
252     res =
253       (((sig_n_prime192.w[2] > 0) || (sig_n_prime192.w[1] > sig_y.w[1])
254 	|| (sig_n_prime192.w[1] == sig_y.w[1]
255 	    && sig_n_prime192.w[0] >
256 	    sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? y : x;
257     BID_RETURN (res);
258   }
259   diff = exp_y - exp_x;
260   // if exp_x is 33 less than exp_y, no need for compensation
261   if (diff > 33) {
262     res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
263     BID_RETURN (res);
264   }
265   if (diff > 19) {	//128 by 128 bit multiply -> 256 bits
266     // adjust the y significand upwards
267     __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
268     // if postitive, return whichever significand is larger
269     // (converse if negative)
270     res =
271       ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
272 	|| (sig_n_prime256.w[1] > sig_x.w[1]
273 	    || (sig_n_prime256.w[1] == sig_x.w[1]
274 		&& sig_n_prime256.w[0] >
275 		sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
276 				 MASK_SIGN)) ? x : y;
277     BID_RETURN (res);
278   }
279   // adjust the y significand upwards
280   __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
281   // if postitive, return whichever significand is larger (converse if negative)
282   res =
283     ((sig_n_prime192.w[2] != 0
284       || (sig_n_prime192.w[1] > sig_x.w[1]
285 	  || (sig_n_prime192.w[1] == sig_x.w[1]
286 	      && sig_n_prime192.w[0] > sig_x.w[0])))
287      ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
288   BID_RETURN (res);
289 }
290 
291 /*****************************************************************************
292  *  BID128 minimum magnitude function - returns greater of two numbers
293  *****************************************************************************/
294 
295 #if DECIMAL_CALL_BY_REFERENCE
296 void
297 bid128_minnum_mag (UINT128 * pres, UINT128 * px,
298 		   UINT128 * py _EXC_FLAGS_PARAM) {
299   UINT128 x = *px;
300   UINT128 y = *py;
301 #else
302 UINT128
303 bid128_minnum_mag (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
304 #endif
305 
306   UINT128 res;
307   int exp_x, exp_y;
308   int diff;
309   UINT128 sig_x, sig_y;
310   UINT192 sig_n_prime192;
311   UINT256 sig_n_prime256;
312 
313   BID_SWAP128 (x);
314   BID_SWAP128 (y);
315 
316   // check for non-canonical x
317   if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
318     x.w[1] = x.w[1] & 0xfe003fffffffffffull;	// clear out G[6]-G[16]
319     // check for non-canonical NaN payload
320     if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
321 	(((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
322 	 (x.w[0] > 0x38c15b09ffffffffull))) {
323       x.w[1] = x.w[1] & 0xffffc00000000000ull;
324       x.w[0] = 0x0ull;
325     }
326   } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) {	// x = inf
327     x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
328     x.w[0] = 0x0ull;
329   } else {	// x is not special
330     // check for non-canonical values - treated as zero
331     if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {	// G0_G1=11
332       // non-canonical
333       x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
334       x.w[0] = 0x0ull;
335     } else {	// G0_G1 != 11
336       if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
337 	  ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
338 	   && x.w[0] > 0x378d8e63ffffffffull)) {
339 	// x is non-canonical if coefficient is larger than 10^34 -1
340 	x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
341 	x.w[0] = 0x0ull;
342       } else {	// canonical
343 	;
344       }
345     }
346   }
347   // check for non-canonical y
348   if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NAN
349     y.w[1] = y.w[1] & 0xfe003fffffffffffull;	// clear out G[6]-G[16]
350     // check for non-canonical NaN payload
351     if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
352 	(((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
353 	 (y.w[0] > 0x38c15b09ffffffffull))) {
354       y.w[1] = y.w[1] & 0xffffc00000000000ull;
355       y.w[0] = 0x0ull;
356     }
357   } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) {	// y = inf
358     y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
359     y.w[0] = 0x0ull;
360   } else {	// y is not special
361     // check for non-canonical values - treated as zero
362     if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {	// G0_G1=11
363       // non-canonical
364       y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
365       y.w[0] = 0x0ull;
366     } else {	// G0_G1 != 11
367       if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
368 	  ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
369 	   && y.w[0] > 0x378d8e63ffffffffull)) {
370 	// y is non-canonical if coefficient is larger than 10^34 -1
371 	y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
372 	y.w[0] = 0x0ull;
373       } else {	// canonical
374 	;
375       }
376     }
377   }
378 
379   // NaN (CASE1)
380   if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
381     if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNaN
382       // if x is SNAN, then return quiet (x)
383       *pfpsf |= INVALID_EXCEPTION;	// set exception if SNaN
384       x.w[1] = x.w[1] & 0xfdffffffffffffffull;	// quietize x
385       res = x;
386     } else {	// x is QNaN
387       if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NAN
388 	if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {	// y is SNAN
389 	  *pfpsf |= INVALID_EXCEPTION;	// set invalid flag
390 	}
391 	res = x;
392       } else {
393 	res = y;
394       }
395     }
396     BID_RETURN (res);
397   } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NaN, but x is not
398     if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
399       *pfpsf |= INVALID_EXCEPTION;	// set exception if SNaN
400       y.w[1] = y.w[1] & 0xfdffffffffffffffull;	// quietize y
401       res = y;
402     } else {
403       // will return x (which is not NaN)
404       res = x;
405     }
406     BID_RETURN (res);
407   }
408   // SIMPLE (CASE2)
409   // if all the bits are the same, these numbers are equal (not Greater).
410   if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
411     res = y;
412     BID_RETURN (res);
413   }
414   // INFINITY (CASE3)
415   if ((x.w[1] & MASK_INF) == MASK_INF) {
416     // if x infinity, it has maximum magnitude.
417     // Check if magnitudes are equal.  If x is negative, return it.
418     res = ((x.w[1] & MASK_SIGN) == MASK_SIGN
419 	   && (y.w[1] & MASK_INF) == MASK_INF) ? x : y;
420     BID_RETURN (res);
421   } else if ((y.w[1] & MASK_INF) == MASK_INF) {
422     // x is finite, so if y is infinity, then x is less in magnitude
423     res = x;
424     BID_RETURN (res);
425   }
426   // CONVERT X
427   sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
428   sig_x.w[0] = x.w[0];
429   exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
430 
431   // CONVERT Y
432   exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
433   sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
434   sig_y.w[0] = y.w[0];
435 
436   // ZERO (CASE4)
437   // some properties:
438   //    (+ZERO == -ZERO) => therefore ignore the sign
439   //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
440   //        therefore ignore the exponent field
441   //    (Any non-canonical # is considered 0)
442   if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
443     res = x;
444     BID_RETURN (res);
445   }
446   if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
447     res = y;
448     BID_RETURN (res);
449   }
450   // REDUNDANT REPRESENTATIONS (CASE6)
451   // check if exponents are the same and significands are the same
452   if (exp_y == exp_x && sig_x.w[1] == sig_y.w[1]
453       && sig_x.w[0] == sig_y.w[0]) {
454     if (x.w[1] & 0x8000000000000000ull) {	// x is negative
455       res = x;
456       BID_RETURN (res);
457     } else {
458       res = y;
459       BID_RETURN (res);
460     }
461   } else if (((sig_x.w[1] > sig_y.w[1] || (sig_x.w[1] == sig_y.w[1]
462 					   && sig_x.w[0] > sig_y.w[0]))
463 	      && exp_x == exp_y)
464 	     || ((sig_x.w[1] > sig_y.w[1]
465 		  || (sig_x.w[1] == sig_y.w[1]
466 		      && sig_x.w[0] >= sig_y.w[0]))
467 		 && exp_x > exp_y)) {
468     // if both components are either bigger or smaller, it is clear what
469     // needs to be done; also if the magnitudes are equal
470     res = y;
471     BID_RETURN (res);
472   } else if (((sig_y.w[1] > sig_x.w[1] || (sig_y.w[1] == sig_x.w[1]
473 					   && sig_y.w[0] > sig_x.w[0]))
474 	      && exp_y == exp_x)
475 	     || ((sig_y.w[1] > sig_x.w[1]
476 		  || (sig_y.w[1] == sig_x.w[1]
477 		      && sig_y.w[0] >= sig_x.w[0]))
478 		 && exp_y > exp_x)) {
479     res = x;
480     BID_RETURN (res);
481   } else {
482     ;	// continue
483   }
484   diff = exp_x - exp_y;
485   // if |exp_x - exp_y| < 33, it comes down to the compensated significand
486   if (diff > 0) {	// to simplify the loop below,
487     // if exp_x is 33 greater than exp_y, no need for compensation
488     if (diff > 33) {
489       res = y;	// difference cannot be greater than 10^33
490       BID_RETURN (res);
491     }
492     if (diff > 19) {	//128 by 128 bit multiply -> 256 bits
493       __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
494       // if positive, return whichever significand is larger
495       // (converse if negative)
496       if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
497 	  && sig_n_prime256.w[1] == sig_y.w[1]
498 	  && (sig_n_prime256.w[0] == sig_y.w[0])) {
499 	res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;	// if equal
500 	BID_RETURN (res);
501       }
502       res = (((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
503 	     || (sig_n_prime256.w[1] > sig_y.w[1])
504 	     || (sig_n_prime256.w[1] == sig_y.w[1]
505 		 && sig_n_prime256.w[0] > sig_y.w[0])) ? y : x;
506       BID_RETURN (res);
507     }
508     __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
509     // if positive, return whichever significand is larger
510     // (converse if negative)
511     if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
512 	&& (sig_n_prime192.w[0] == sig_y.w[0])) {
513       // if = in magnitude, return +, (if possible)
514       res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
515       BID_RETURN (res);
516     }
517     res = ((sig_n_prime192.w[2] > 0)
518 	   || (sig_n_prime192.w[1] > sig_y.w[1])
519 	   || (sig_n_prime192.w[1] == sig_y.w[1]
520 	       && sig_n_prime192.w[0] > sig_y.w[0])) ? y : x;
521     BID_RETURN (res);
522   }
523   diff = exp_y - exp_x;
524   // if exp_x is 33 less than exp_y, no need for compensation
525   if (diff > 33) {
526     res = x;
527     BID_RETURN (res);
528   }
529   if (diff > 19) {	//128 by 128 bit multiply -> 256 bits
530     // adjust the y significand upwards
531     __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
532     // if positive, return whichever significand is larger
533     // (converse if negative)
534     if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
535 	&& sig_n_prime256.w[1] == sig_x.w[1]
536 	&& (sig_n_prime256.w[0] == sig_x.w[0])) {
537       // if = in magnitude, return +, (if possible)
538       res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
539       BID_RETURN (res);
540     }
541     res = (sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
542 	   && (sig_n_prime256.w[1] < sig_x.w[1]
543 	       || (sig_n_prime256.w[1] == sig_x.w[1]
544 		   && sig_n_prime256.w[0] < sig_x.w[0]))) ? y : x;
545     BID_RETURN (res);
546   }
547   // adjust the y significand upwards
548   __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
549   // if positive, return whichever significand is larger (converse if negative)
550   if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
551       && (sig_n_prime192.w[0] == sig_x.w[0])) {
552     // if = in magnitude, return +, if possible)
553     res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
554     BID_RETURN (res);
555   }
556   res = (sig_n_prime192.w[2] == 0
557 	 && (sig_n_prime192.w[1] < sig_x.w[1]
558 	     || (sig_n_prime192.w[1] == sig_x.w[1]
559 		 && sig_n_prime192.w[0] < sig_x.w[0]))) ? y : x;
560   BID_RETURN (res);
561 }
562 
563 /*****************************************************************************
564  *  BID128 maximum function - returns greater of two numbers
565  *****************************************************************************/
566 
567 #if DECIMAL_CALL_BY_REFERENCE
568 void
569 bid128_maxnum (UINT128 * pres, UINT128 * px,
570 	       UINT128 * py _EXC_FLAGS_PARAM) {
571   UINT128 x = *px;
572   UINT128 y = *py;
573 #else
574 UINT128
575 bid128_maxnum (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
576 #endif
577 
578   UINT128 res;
579   int exp_x, exp_y;
580   int diff;
581   UINT128 sig_x, sig_y;
582   UINT192 sig_n_prime192;
583   UINT256 sig_n_prime256;
584   char x_is_zero = 0, y_is_zero = 0;
585 
586   BID_SWAP128 (x);
587   BID_SWAP128 (y);
588 
589   // check for non-canonical x
590   if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
591     x.w[1] = x.w[1] & 0xfe003fffffffffffull;	// clear out G[6]-G[16]
592     // check for non-canonical NaN payload
593     if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
594 	(((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
595 	 (x.w[0] > 0x38c15b09ffffffffull))) {
596       x.w[1] = x.w[1] & 0xffffc00000000000ull;
597       x.w[0] = 0x0ull;
598     }
599   } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) {	// x = inf
600     x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
601     x.w[0] = 0x0ull;
602   } else {	// x is not special
603     // check for non-canonical values - treated as zero
604     if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {	// G0_G1=11
605       // non-canonical
606       x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
607       x.w[0] = 0x0ull;
608     } else {	// G0_G1 != 11
609       if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
610 	  ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
611 	   && x.w[0] > 0x378d8e63ffffffffull)) {
612 	// x is non-canonical if coefficient is larger than 10^34 -1
613 	x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
614 	x.w[0] = 0x0ull;
615       } else {	// canonical
616 	;
617       }
618     }
619   }
620   // check for non-canonical y
621   if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NAN
622     y.w[1] = y.w[1] & 0xfe003fffffffffffull;	// clear out G[6]-G[16]
623     // check for non-canonical NaN payload
624     if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
625 	(((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
626 	 (y.w[0] > 0x38c15b09ffffffffull))) {
627       y.w[1] = y.w[1] & 0xffffc00000000000ull;
628       y.w[0] = 0x0ull;
629     }
630   } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) {	// y = inf
631     y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
632     y.w[0] = 0x0ull;
633   } else {	// y is not special
634     // check for non-canonical values - treated as zero
635     if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {	// G0_G1=11
636       // non-canonical
637       y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
638       y.w[0] = 0x0ull;
639     } else {	// G0_G1 != 11
640       if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
641 	  ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
642 	   && y.w[0] > 0x378d8e63ffffffffull)) {
643 	// y is non-canonical if coefficient is larger than 10^34 -1
644 	y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
645 	y.w[0] = 0x0ull;
646       } else {	// canonical
647 	;
648       }
649     }
650   }
651 
652   // NaN (CASE1)
653   if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
654     if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNaN
655       // if x is SNAN, then return quiet (x)
656       *pfpsf |= INVALID_EXCEPTION;	// set exception if SNaN
657       x.w[1] = x.w[1] & 0xfdffffffffffffffull;	// quietize x
658       res = x;
659     } else {	// x is QNaN
660       if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NAN
661 	if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {	// y is SNAN
662 	  *pfpsf |= INVALID_EXCEPTION;	// set invalid flag
663 	}
664 	res = x;
665       } else {
666 	res = y;
667       }
668     }
669     BID_RETURN (res);
670   } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NaN, but x is not
671     if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
672       *pfpsf |= INVALID_EXCEPTION;	// set exception if SNaN
673       y.w[1] = y.w[1] & 0xfdffffffffffffffull;	// quietize y
674       res = y;
675     } else {
676       // will return x (which is not NaN)
677       res = x;
678     }
679     BID_RETURN (res);
680   }
681   // SIMPLE (CASE2)
682   // if all the bits are the same, these numbers are equal (not Greater).
683   if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
684     res = x;
685     BID_RETURN (res);
686   }
687   // INFINITY (CASE3)
688   if ((x.w[1] & MASK_INF) == MASK_INF) {
689     res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
690     BID_RETURN (res);
691   } else if ((y.w[1] & MASK_INF) == MASK_INF) {
692     // x is finite, so if y is positive infinity, then x is less, return 0
693     //                 if y is negative infinity, then x is greater, return 1
694     res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
695     BID_RETURN (res);
696   }
697   // CONVERT X
698   sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
699   sig_x.w[0] = x.w[0];
700   exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
701 
702   // CONVERT Y
703   exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
704   sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
705   sig_y.w[0] = y.w[0];
706 
707   // ZERO (CASE4)
708   // some properties:
709   //    (+ZERO == -ZERO) => therefore ignore the sign
710   //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
711   //        therefore ignore the exponent field
712   //    (Any non-canonical # is considered 0)
713   if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
714     x_is_zero = 1;
715   }
716   if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
717     y_is_zero = 1;
718   }
719 
720   if (x_is_zero && y_is_zero) {
721     // if both numbers are zero, neither is greater => return either number
722     res = x;
723     BID_RETURN (res);
724   } else if (x_is_zero) {
725     // is x is zero, it is greater if Y is negative
726     res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
727     BID_RETURN (res);
728   } else if (y_is_zero) {
729     // is y is zero, X is greater if it is positive
730     res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
731     BID_RETURN (res);
732   }
733   // OPPOSITE SIGN (CASE5)
734   // now, if the sign bits differ, x is greater if y is negative
735   if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
736     res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
737     BID_RETURN (res);
738   }
739   // REDUNDANT REPRESENTATIONS (CASE6)
740   // if exponents are the same, then we have a simple comparison of
741   // the significands
742   if (exp_y == exp_x) {
743     res = (((sig_x.w[1] > sig_y.w[1]) || (sig_x.w[1] == sig_y.w[1] &&
744 					  sig_x.w[0] >= sig_y.w[0])) ^
745 	   ((x.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
746     BID_RETURN (res);
747   }
748   // if both components are either bigger or smaller, it is clear what
749   // needs to be done
750   if ((sig_x.w[1] > sig_y.w[1]
751        || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
752       && exp_x >= exp_y) {
753     res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
754     BID_RETURN (res);
755   }
756   if ((sig_x.w[1] < sig_y.w[1]
757        || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
758       && exp_x <= exp_y) {
759     res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
760     BID_RETURN (res);
761   }
762   diff = exp_x - exp_y;
763   // if |exp_x - exp_y| < 33, it comes down to the compensated significand
764   if (diff > 0) {	// to simplify the loop below,
765     // if exp_x is 33 greater than exp_y, no need for compensation
766     if (diff > 33) {
767       // difference cannot be greater than 10^33
768       res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
769       BID_RETURN (res);
770     }
771     if (diff > 19) {	//128 by 128 bit multiply -> 256 bits
772       __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
773       // if postitive, return whichever significand is larger
774       // (converse if negative)
775       res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
776 	      || (sig_n_prime256.w[1] > sig_y.w[1])
777 	      || (sig_n_prime256.w[1] == sig_y.w[1]
778 		  && sig_n_prime256.w[0] >
779 		  sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) ==
780 				  MASK_SIGN)) ? x : y;
781       BID_RETURN (res);
782     }
783     __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
784     // if postitive, return whichever significand is larger
785     // (converse if negative)
786     res =
787       (((sig_n_prime192.w[2] > 0) || (sig_n_prime192.w[1] > sig_y.w[1])
788 	|| (sig_n_prime192.w[1] == sig_y.w[1]
789 	    && sig_n_prime192.w[0] >
790 	    sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
791     BID_RETURN (res);
792   }
793   diff = exp_y - exp_x;
794   // if exp_x is 33 less than exp_y, no need for compensation
795   if (diff > 33) {
796     res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
797     BID_RETURN (res);
798   }
799   if (diff > 19) {	//128 by 128 bit multiply -> 256 bits
800     // adjust the y significand upwards
801     __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
802     // if postitive, return whichever significand is larger
803     // (converse if negative)
804     res =
805       ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
806 	|| (sig_n_prime256.w[1] > sig_x.w[1]
807 	    || (sig_n_prime256.w[1] == sig_x.w[1]
808 		&& sig_n_prime256.w[0] >
809 		sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) !=
810 				 MASK_SIGN)) ? x : y;
811     BID_RETURN (res);
812   }
813   // adjust the y significand upwards
814   __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
815   // if postitive, return whichever significand is larger (converse if negative)
816   res =
817     ((sig_n_prime192.w[2] != 0
818       || (sig_n_prime192.w[1] > sig_x.w[1]
819 	  || (sig_n_prime192.w[1] == sig_x.w[1]
820 	      && sig_n_prime192.w[0] >
821 	      sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) !=
822 			       MASK_SIGN)) ? x : y;
823   BID_RETURN (res);
824 }
825 
826 /*****************************************************************************
827  *  BID128 maximum magnitude function - returns greater of two numbers
828  *****************************************************************************/
829 
830 #if DECIMAL_CALL_BY_REFERENCE
831 void
832 bid128_maxnum_mag (UINT128 * pres, UINT128 * px,
833 		   UINT128 * py _EXC_FLAGS_PARAM) {
834   UINT128 x = *px;
835   UINT128 y = *py;
836 #else
837 UINT128
838 bid128_maxnum_mag (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
839 #endif
840 
841   UINT128 res;
842   int exp_x, exp_y;
843   int diff;
844   UINT128 sig_x, sig_y;
845   UINT192 sig_n_prime192;
846   UINT256 sig_n_prime256;
847 
848   BID_SWAP128 (x);
849   BID_SWAP128 (y);
850 
851   // check for non-canonical x
852   if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
853     x.w[1] = x.w[1] & 0xfe003fffffffffffull;	// clear out G[6]-G[16]
854     // check for non-canonical NaN payload
855     if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
856 	(((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
857 	 (x.w[0] > 0x38c15b09ffffffffull))) {
858       x.w[1] = x.w[1] & 0xffffc00000000000ull;
859       x.w[0] = 0x0ull;
860     }
861   } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) {	// x = inf
862     x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
863     x.w[0] = 0x0ull;
864   } else {	// x is not special
865     // check for non-canonical values - treated as zero
866     if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {	// G0_G1=11
867       // non-canonical
868       x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
869       x.w[0] = 0x0ull;
870     } else {	// G0_G1 != 11
871       if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
872 	  ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
873 	   && x.w[0] > 0x378d8e63ffffffffull)) {
874 	// x is non-canonical if coefficient is larger than 10^34 -1
875 	x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
876 	x.w[0] = 0x0ull;
877       } else {	// canonical
878 	;
879       }
880     }
881   }
882   // check for non-canonical y
883   if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NAN
884     y.w[1] = y.w[1] & 0xfe003fffffffffffull;	// clear out G[6]-G[16]
885     // check for non-canonical NaN payload
886     if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
887 	(((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
888 	 (y.w[0] > 0x38c15b09ffffffffull))) {
889       y.w[1] = y.w[1] & 0xffffc00000000000ull;
890       y.w[0] = 0x0ull;
891     }
892   } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) {	// y = inf
893     y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
894     y.w[0] = 0x0ull;
895   } else {	// y is not special
896     // check for non-canonical values - treated as zero
897     if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {	// G0_G1=11
898       // non-canonical
899       y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
900       y.w[0] = 0x0ull;
901     } else {	// G0_G1 != 11
902       if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
903 	  ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull &&
904 	   y.w[0] > 0x378d8e63ffffffffull)) {
905 	// y is non-canonical if coefficient is larger than 10^34 -1
906 	y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
907 	y.w[0] = 0x0ull;
908       } else {	// canonical
909 	;
910       }
911     }
912   }
913 
914   // NaN (CASE1)
915   if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
916     if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNaN
917       // if x is SNAN, then return quiet (x)
918       *pfpsf |= INVALID_EXCEPTION;	// set exception if SNaN
919       x.w[1] = x.w[1] & 0xfdffffffffffffffull;	// quietize x
920       res = x;
921     } else {	// x is QNaN
922       if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NAN
923 	if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {	// y is SNAN
924 	  *pfpsf |= INVALID_EXCEPTION;	// set invalid flag
925 	}
926 	res = x;
927       } else {
928 	res = y;
929       }
930     }
931     BID_RETURN (res);
932   } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NaN, but x is not
933     if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
934       *pfpsf |= INVALID_EXCEPTION;	// set exception if SNaN
935       y.w[1] = y.w[1] & 0xfdffffffffffffffull;	// quietize y
936       res = y;
937     } else {
938       // will return x (which is not NaN)
939       res = x;
940     }
941     BID_RETURN (res);
942   }
943   // SIMPLE (CASE2)
944   // if all the bits are the same, these numbers are equal (not Greater).
945   if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
946     res = y;
947     BID_RETURN (res);
948   }
949   // INFINITY (CASE3)
950   if ((x.w[1] & MASK_INF) == MASK_INF) {
951     // if x infinity, it has maximum magnitude
952     res = ((x.w[1] & MASK_SIGN) == MASK_SIGN
953 	   && (y.w[1] & MASK_INF) == MASK_INF) ? y : x;
954     BID_RETURN (res);
955   } else if ((y.w[1] & MASK_INF) == MASK_INF) {
956     // x is finite, so if y is positive infinity, then x is less, return 0
957     //                 if y is negative infinity, then x is greater, return 1
958     res = y;
959     BID_RETURN (res);
960   }
961   // CONVERT X
962   sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
963   sig_x.w[0] = x.w[0];
964   exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
965 
966   // CONVERT Y
967   exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
968   sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
969   sig_y.w[0] = y.w[0];
970 
971   // ZERO (CASE4)
972   // some properties:
973   //    (+ZERO == -ZERO) => therefore ignore the sign
974   //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
975   //         therefore ignore the exponent field
976   //    (Any non-canonical # is considered 0)
977   if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
978     res = y;
979     BID_RETURN (res);
980   }
981   if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
982     res = x;
983     BID_RETURN (res);
984   }
985   // REDUNDANT REPRESENTATIONS (CASE6)
986   if (exp_y == exp_x && sig_x.w[1] == sig_y.w[1]
987       && sig_x.w[0] == sig_y.w[0]) {
988     // check if exponents are the same and significands are the same
989     if (x.w[1] & 0x8000000000000000ull) {	// x is negative
990       res = y;
991       BID_RETURN (res);
992     } else {
993       res = x;
994       BID_RETURN (res);
995     }
996   } else if (((sig_x.w[1] > sig_y.w[1] || (sig_x.w[1] == sig_y.w[1]
997 					   && sig_x.w[0] > sig_y.w[0]))
998 	      && exp_x == exp_y)
999 	     || ((sig_x.w[1] > sig_y.w[1]
1000 		  || (sig_x.w[1] == sig_y.w[1]
1001 		      && sig_x.w[0] >= sig_y.w[0]))
1002 		 && exp_x > exp_y)) {
1003     // if both components are either bigger or smaller, it is clear what
1004     // needs to be done; also if the magnitudes are equal
1005     res = x;
1006     BID_RETURN (res);
1007   } else if (((sig_y.w[1] > sig_x.w[1] || (sig_y.w[1] == sig_x.w[1]
1008 					   && sig_y.w[0] > sig_x.w[0]))
1009 	      && exp_y == exp_x)
1010 	     || ((sig_y.w[1] > sig_x.w[1]
1011 		  || (sig_y.w[1] == sig_x.w[1]
1012 		      && sig_y.w[0] >= sig_x.w[0]))
1013 		 && exp_y > exp_x)) {
1014     res = y;
1015     BID_RETURN (res);
1016   } else {
1017     ;	// continue
1018   }
1019   diff = exp_x - exp_y;
1020   // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1021   if (diff > 0) {	// to simplify the loop below,
1022     // if exp_x is 33 greater than exp_y, no need for compensation
1023     if (diff > 33) {
1024       res = x;	// difference cannot be greater than 10^33
1025       BID_RETURN (res);
1026     }
1027     if (diff > 19) {	//128 by 128 bit multiply -> 256 bits
1028       __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
1029       // if postitive, return whichever significand is larger
1030       // (converse if negative)
1031       if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
1032 	  && sig_n_prime256.w[1] == sig_y.w[1]
1033 	  && (sig_n_prime256.w[0] == sig_y.w[0])) {
1034 	res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;	// if equal
1035 	BID_RETURN (res);
1036       }
1037       res = (((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
1038 	     || (sig_n_prime256.w[1] > sig_y.w[1])
1039 	     || (sig_n_prime256.w[1] == sig_y.w[1]
1040 		 && sig_n_prime256.w[0] > sig_y.w[0])) ? x : y;
1041       BID_RETURN (res);
1042     }
1043     __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
1044     // if postitive, return whichever significand is larger (converse if negative)
1045     if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
1046 	&& (sig_n_prime192.w[0] == sig_y.w[0])) {
1047       // if equal, return positive magnitude
1048       res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
1049       BID_RETURN (res);
1050     }
1051     res = ((sig_n_prime192.w[2] > 0)
1052 	   || (sig_n_prime192.w[1] > sig_y.w[1])
1053 	   || (sig_n_prime192.w[1] == sig_y.w[1]
1054 	       && sig_n_prime192.w[0] > sig_y.w[0])) ? x : y;
1055     BID_RETURN (res);
1056   }
1057   diff = exp_y - exp_x;
1058   // if exp_x is 33 less than exp_y, no need for compensation
1059   if (diff > 33) {
1060     res = y;
1061     BID_RETURN (res);
1062   }
1063   if (diff > 19) {	//128 by 128 bit multiply -> 256 bits
1064     // adjust the y significand upwards
1065     __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
1066     // if postitive, return whichever significand is larger
1067     // (converse if negative)
1068     if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
1069 	&& sig_n_prime256.w[1] == sig_x.w[1]
1070 	&& (sig_n_prime256.w[0] == sig_x.w[0])) {
1071       // if equal, return positive (if possible)
1072       res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
1073       BID_RETURN (res);
1074     }
1075     res = (sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
1076 	   && (sig_n_prime256.w[1] < sig_x.w[1]
1077 	       || (sig_n_prime256.w[1] == sig_x.w[1]
1078 		   && sig_n_prime256.w[0] < sig_x.w[0]))) ? x : y;
1079     BID_RETURN (res);
1080   }
1081   // adjust the y significand upwards
1082   __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
1083   // if postitive, return whichever significand is larger (converse if negative)
1084   if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
1085       && (sig_n_prime192.w[0] == sig_x.w[0])) {
1086     // if equal, return positive (if possible)
1087     res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
1088     BID_RETURN (res);
1089   }
1090   res = (sig_n_prime192.w[2] == 0
1091 	 && (sig_n_prime192.w[1] < sig_x.w[1]
1092 	     || (sig_n_prime192.w[1] == sig_x.w[1]
1093 		 && sig_n_prime192.w[0] < sig_x.w[0]))) ? x : y;
1094   BID_RETURN (res);
1095 }
1096