1 /* Copyright (C) 2007-2019 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 static const UINT64 mult_factor[16] = {
27   1ull, 10ull, 100ull, 1000ull,
28   10000ull, 100000ull, 1000000ull, 10000000ull,
29   100000000ull, 1000000000ull, 10000000000ull, 100000000000ull,
30   1000000000000ull, 10000000000000ull,
31   100000000000000ull, 1000000000000000ull
32 };
33 
34 /*****************************************************************************
35  *    BID64 non-computational functions:
36  *         - bid64_isSigned
37  *         - bid64_isNormal
38  *         - bid64_isSubnormal
39  *         - bid64_isFinite
40  *         - bid64_isZero
41  *         - bid64_isInf
42  *         - bid64_isSignaling
43  *         - bid64_isCanonical
44  *         - bid64_isNaN
45  *         - bid64_copy
46  *         - bid64_negate
47  *         - bid64_abs
48  *         - bid64_copySign
49  *         - bid64_class
50  *         - bid64_sameQuantum
51  *         - bid64_totalOrder
52  *         - bid64_totalOrderMag
53  *         - bid64_radix
54  ****************************************************************************/
55 
56 #if DECIMAL_CALL_BY_REFERENCE
57 void
bid64_isSigned(int * pres,UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM)58 bid64_isSigned (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
59   UINT64 x = *px;
60 #else
61 int
62 bid64_isSigned (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
63 #endif
64   int res;
65 
66   res = ((x & MASK_SIGN) == MASK_SIGN);
67   BID_RETURN (res);
68 }
69 
70 // return 1 iff x is not zero, nor NaN nor subnormal nor infinity
71 #if DECIMAL_CALL_BY_REFERENCE
72 void
73 bid64_isNormal (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
74   UINT64 x = *px;
75 #else
76 int
77 bid64_isNormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
78 #endif
79   int res;
80   UINT128 sig_x_prime;
81   UINT64 sig_x;
82   unsigned int exp_x;
83 
84   if ((x & MASK_INF) == MASK_INF) {	// x is either INF or NaN
85     res = 0;
86   } else {
87     // decode number into exponent and significand
88     if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
89       sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
90       // check for zero or non-canonical
91       if (sig_x > 9999999999999999ull || sig_x == 0) {
92 	res = 0;	// zero or non-canonical
93 	BID_RETURN (res);
94       }
95       exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
96     } else {
97       sig_x = (x & MASK_BINARY_SIG1);
98       if (sig_x == 0) {
99 	res = 0;	// zero
100 	BID_RETURN (res);
101       }
102       exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
103     }
104     // if exponent is less than -383, the number may be subnormal
105     // if (exp_x - 398 = -383) the number may be subnormal
106     if (exp_x < 15) {
107       __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
108       if (sig_x_prime.w[1] == 0
109 	  && sig_x_prime.w[0] < 1000000000000000ull) {
110 	res = 0;	// subnormal
111       } else {
112 	res = 1;	// normal
113       }
114     } else {
115       res = 1;	// normal
116     }
117   }
118   BID_RETURN (res);
119 }
120 
121 // return 1 iff x is not zero, nor NaN nor normal nor infinity
122 #if DECIMAL_CALL_BY_REFERENCE
123 void
124 bid64_isSubnormal (int *pres,
125 		   UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
126   UINT64 x = *px;
127 #else
128 int
129 bid64_isSubnormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
130 #endif
131   int res;
132   UINT128 sig_x_prime;
133   UINT64 sig_x;
134   unsigned int exp_x;
135 
136   if ((x & MASK_INF) == MASK_INF) {	// x is either INF or NaN
137     res = 0;
138   } else {
139     // decode number into exponent and significand
140     if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
141       sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
142       // check for zero or non-canonical
143       if (sig_x > 9999999999999999ull || sig_x == 0) {
144 	res = 0;	// zero or non-canonical
145 	BID_RETURN (res);
146       }
147       exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
148     } else {
149       sig_x = (x & MASK_BINARY_SIG1);
150       if (sig_x == 0) {
151 	res = 0;	// zero
152 	BID_RETURN (res);
153       }
154       exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
155     }
156     // if exponent is less than -383, the number may be subnormal
157     // if (exp_x - 398 = -383) the number may be subnormal
158     if (exp_x < 15) {
159       __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
160       if (sig_x_prime.w[1] == 0
161 	  && sig_x_prime.w[0] < 1000000000000000ull) {
162 	res = 1;	// subnormal
163       } else {
164 	res = 0;	// normal
165       }
166     } else {
167       res = 0;	// normal
168     }
169   }
170   BID_RETURN (res);
171 }
172 
173 //iff x is zero, subnormal or normal (not infinity or NaN)
174 #if DECIMAL_CALL_BY_REFERENCE
175 void
176 bid64_isFinite (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
177   UINT64 x = *px;
178 #else
179 int
180 bid64_isFinite (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
181 #endif
182   int res;
183 
184   res = ((x & MASK_INF) != MASK_INF);
185   BID_RETURN (res);
186 }
187 
188 #if DECIMAL_CALL_BY_REFERENCE
189 void
190 bid64_isZero (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
191   UINT64 x = *px;
192 #else
193 int
194 bid64_isZero (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
195 #endif
196   int res;
197 
198   // if infinity or nan, return 0
199   if ((x & MASK_INF) == MASK_INF) {
200     res = 0;
201   } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
202     // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1]
203     // => sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
204     // if(sig_x > 9999999999999999ull) {return 1;}
205     res =
206       (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
207        9999999999999999ull);
208   } else {
209     res = ((x & MASK_BINARY_SIG1) == 0);
210   }
211   BID_RETURN (res);
212 }
213 
214 #if DECIMAL_CALL_BY_REFERENCE
215 void
216 bid64_isInf (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
217   UINT64 x = *px;
218 #else
219 int
220 bid64_isInf (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
221 #endif
222   int res;
223 
224   res = ((x & MASK_INF) == MASK_INF) && ((x & MASK_NAN) != MASK_NAN);
225   BID_RETURN (res);
226 }
227 
228 #if DECIMAL_CALL_BY_REFERENCE
229 void
230 bid64_isSignaling (int *pres,
231 		   UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
232   UINT64 x = *px;
233 #else
234 int
235 bid64_isSignaling (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
236 #endif
237   int res;
238 
239   res = ((x & MASK_SNAN) == MASK_SNAN);
240   BID_RETURN (res);
241 }
242 
243 #if DECIMAL_CALL_BY_REFERENCE
244 void
245 bid64_isCanonical (int *pres,
246 		   UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
247   UINT64 x = *px;
248 #else
249 int
250 bid64_isCanonical (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
251 #endif
252   int res;
253 
254   if ((x & MASK_NAN) == MASK_NAN) {	// NaN
255     if (x & 0x01fc000000000000ull) {
256       res = 0;
257     } else if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {	// payload
258       res = 0;
259     } else {
260       res = 1;
261     }
262   } else if ((x & MASK_INF) == MASK_INF) {
263     if (x & 0x03ffffffffffffffull) {
264       res = 0;
265     } else {
266       res = 1;
267     }
268   } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {	// 54-bit coeff.
269     res =
270       (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) <=
271        9999999999999999ull);
272   } else {	// 53-bit coeff.
273     res = 1;
274   }
275   BID_RETURN (res);
276 }
277 
278 #if DECIMAL_CALL_BY_REFERENCE
279 void
280 bid64_isNaN (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
281   UINT64 x = *px;
282 #else
283 int
284 bid64_isNaN (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
285 #endif
286   int res;
287 
288   res = ((x & MASK_NAN) == MASK_NAN);
289   BID_RETURN (res);
290 }
291 
292 // copies a floating-point operand x to destination y, with no change
293 #if DECIMAL_CALL_BY_REFERENCE
294 void
295 bid64_copy (UINT64 * pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
296   UINT64 x = *px;
297 #else
298 UINT64
299 bid64_copy (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
300 #endif
301   UINT64 res;
302 
303   res = x;
304   BID_RETURN (res);
305 }
306 
307 // copies a floating-point operand x to destination y, reversing the sign
308 #if DECIMAL_CALL_BY_REFERENCE
309 void
310 bid64_negate (UINT64 * pres,
311 	      UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
312   UINT64 x = *px;
313 #else
314 UINT64
315 bid64_negate (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
316 #endif
317   UINT64 res;
318 
319   res = x ^ MASK_SIGN;
320   BID_RETURN (res);
321 }
322 
323 // copies a floating-point operand x to destination y, changing the sign to positive
324 #if DECIMAL_CALL_BY_REFERENCE
325 void
326 bid64_abs (UINT64 * pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
327   UINT64 x = *px;
328 #else
329 UINT64
330 bid64_abs (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
331 #endif
332   UINT64 res;
333 
334   res = x & ~MASK_SIGN;
335   BID_RETURN (res);
336 }
337 
338 // copies operand x to destination in the same format as x, but
339 // with the sign of y
340 #if DECIMAL_CALL_BY_REFERENCE
341 void
342 bid64_copySign (UINT64 * pres, UINT64 * px,
343 		UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
344   UINT64 x = *px;
345   UINT64 y = *py;
346 #else
347 UINT64
348 bid64_copySign (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
349 #endif
350   UINT64 res;
351 
352   res = (x & ~MASK_SIGN) | (y & MASK_SIGN);
353   BID_RETURN (res);
354 }
355 
356 #if DECIMAL_CALL_BY_REFERENCE
357 void
358 bid64_class (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
359   UINT64 x = *px;
360 #else
361 int
362 bid64_class (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
363 #endif
364   int res;
365   UINT128 sig_x_prime;
366   UINT64 sig_x;
367   int exp_x;
368 
369   if ((x & MASK_NAN) == MASK_NAN) {
370     // is the NaN signaling?
371     if ((x & MASK_SNAN) == MASK_SNAN) {
372       res = signalingNaN;
373       BID_RETURN (res);
374     }
375     // if NaN and not signaling, must be quietNaN
376     res = quietNaN;
377     BID_RETURN (res);
378   } else if ((x & MASK_INF) == MASK_INF) {
379     // is the Infinity negative?
380     if ((x & MASK_SIGN) == MASK_SIGN) {
381       res = negativeInfinity;
382     } else {
383       // otherwise, must be positive infinity
384       res = positiveInfinity;
385     }
386     BID_RETURN (res);
387   } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
388     // decode number into exponent and significand
389     sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
390     // check for zero or non-canonical
391     if (sig_x > 9999999999999999ull || sig_x == 0) {
392       if ((x & MASK_SIGN) == MASK_SIGN) {
393 	res = negativeZero;
394       } else {
395 	res = positiveZero;
396       }
397       BID_RETURN (res);
398     }
399     exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
400   } else {
401     sig_x = (x & MASK_BINARY_SIG1);
402     if (sig_x == 0) {
403       res =
404 	((x & MASK_SIGN) == MASK_SIGN) ? negativeZero : positiveZero;
405       BID_RETURN (res);
406     }
407     exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
408   }
409   // if exponent is less than -383, number may be subnormal
410   //  if (exp_x - 398 < -383)
411   if (exp_x < 15) {	// sig_x *10^exp_x
412     __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
413     if (sig_x_prime.w[1] == 0
414 	&& (sig_x_prime.w[0] < 1000000000000000ull)) {
415       res =
416 	((x & MASK_SIGN) ==
417 	 MASK_SIGN) ? negativeSubnormal : positiveSubnormal;
418       BID_RETURN (res);
419     }
420   }
421   // otherwise, normal number, determine the sign
422   res =
423     ((x & MASK_SIGN) == MASK_SIGN) ? negativeNormal : positiveNormal;
424   BID_RETURN (res);
425 }
426 
427 // true if the exponents of x and y are the same, false otherwise.
428 // The special cases of sameQuantum (NaN, NaN) and sameQuantum (Inf, Inf) are
429 // true.
430 // If exactly one operand is infinite or exactly one operand is NaN, then false
431 #if DECIMAL_CALL_BY_REFERENCE
432 void
433 bid64_sameQuantum (int *pres, UINT64 * px,
434 		   UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
435   UINT64 x = *px;
436   UINT64 y = *py;
437 #else
438 int
439 bid64_sameQuantum (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
440 #endif
441   int res;
442   unsigned int exp_x, exp_y;
443 
444   // if both operands are NaN, return true; if just one is NaN, return false
445   if ((x & MASK_NAN) == MASK_NAN || ((y & MASK_NAN) == MASK_NAN)) {
446     res = ((x & MASK_NAN) == MASK_NAN && (y & MASK_NAN) == MASK_NAN);
447     BID_RETURN (res);
448   }
449   // if both operands are INF, return true; if just one is INF, return false
450   if ((x & MASK_INF) == MASK_INF || (y & MASK_INF) == MASK_INF) {
451     res = ((x & MASK_INF) == MASK_INF && (y & MASK_INF) == MASK_INF);
452     BID_RETURN (res);
453   }
454   // decode exponents for both numbers, and return true if they match
455   if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
456     exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
457   } else {
458     exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
459   }
460   if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
461     exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
462   } else {
463     exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
464   }
465   res = (exp_x == exp_y);
466   BID_RETURN (res);
467 }
468 
469 #if DECIMAL_CALL_BY_REFERENCE
470 void
471 bid64_totalOrder (int *pres, UINT64 * px,
472 		  UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
473   UINT64 x = *px;
474   UINT64 y = *py;
475 #else
476 int
477 bid64_totalOrder (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
478 #endif
479   int res;
480   int exp_x, exp_y;
481   UINT64 sig_x, sig_y, pyld_y, pyld_x;
482   UINT128 sig_n_prime;
483   char x_is_zero = 0, y_is_zero = 0;
484 
485   // NaN (CASE1)
486   // if x and y are unordered numerically because either operand is NaN
487   //    (1) totalOrder(-NaN, number) is true
488   //    (2) totalOrder(number, +NaN) is true
489   //    (3) if x and y are both NaN:
490   //           i) negative sign bit < positive sign bit
491   //           ii) signaling < quiet for +NaN, reverse for -NaN
492   //           iii) lesser payload < greater payload for +NaN (reverse for -NaN)
493   //           iv) else if bitwise identical (in canonical form), return 1
494   if ((x & MASK_NAN) == MASK_NAN) {
495     // if x is -NaN
496     if ((x & MASK_SIGN) == MASK_SIGN) {
497       // return true, unless y is -NaN also
498       if ((y & MASK_NAN) != MASK_NAN || (y & MASK_SIGN) != MASK_SIGN) {
499 	res = 1;	// y is a number, return 1
500 	BID_RETURN (res);
501       } else {	// if y and x are both -NaN
502 	// if x and y are both -sNaN or both -qNaN, we have to compare payloads
503 	// this xnor statement evaluates to true if both are sNaN or qNaN
504 	if (!
505 	    (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
506 					       MASK_SNAN))) {
507 	  // it comes down to the payload.  we want to return true if x has a
508 	  // larger payload, or if the payloads are equal (canonical forms
509 	  // are bitwise identical)
510 	  pyld_y = y & 0x0003ffffffffffffull;
511 	  pyld_x = x & 0x0003ffffffffffffull;
512 	  if (pyld_y > 999999999999999ull || pyld_y == 0) {
513 	    // if y is zero, x must be less than or numerically equal
514 	    // y's payload is 0
515 	    res = 1;
516 	    BID_RETURN (res);
517 	  }
518 	  // if x is zero and y isn't, x has the smaller payload
519 	  // definitely (since we know y isn't 0 at this point)
520 	  if (pyld_x > 999999999999999ull || pyld_x == 0) {
521 	    // x's payload is 0
522 	    res = 0;
523 	    BID_RETURN (res);
524 	  }
525 	  res = (pyld_x >= pyld_y);
526 	  BID_RETURN (res);
527 	} else {
528 	  // either x = -sNaN and y = -qNaN or x = -qNaN and y = -sNaN
529 	  res = (y & MASK_SNAN) == MASK_SNAN;	// totalOrder(-qNaN, -sNaN) == 1
530 	  BID_RETURN (res);
531 	}
532       }
533     } else {	// x is +NaN
534       // return false, unless y is +NaN also
535       if ((y & MASK_NAN) != MASK_NAN || (y & MASK_SIGN) == MASK_SIGN) {
536 	res = 0;	// y is a number, return 1
537 	BID_RETURN (res);
538       } else {
539 	// x and y are both +NaN;
540 	// must investigate payload if both quiet or both signaling
541 	// this xnor statement will be true if both x and y are +qNaN or +sNaN
542 	if (!
543 	    (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
544 					       MASK_SNAN))) {
545 	  // it comes down to the payload.  we want to return true if x has a
546 	  // smaller payload, or if the payloads are equal (canonical forms
547 	  // are bitwise identical)
548 	  pyld_y = y & 0x0003ffffffffffffull;
549 	  pyld_x = x & 0x0003ffffffffffffull;
550 	  // if x is zero and y isn't, x has the smaller
551 	  // payload definitely (since we know y isn't 0 at this point)
552 	  if (pyld_x > 999999999999999ull || pyld_x == 0) {
553 	    res = 1;
554 	    BID_RETURN (res);
555 	  }
556 	  if (pyld_y > 999999999999999ull || pyld_y == 0) {
557 	    // if y is zero, x must be less than or numerically equal
558 	    res = 0;
559 	    BID_RETURN (res);
560 	  }
561 	  res = (pyld_x <= pyld_y);
562 	  BID_RETURN (res);
563 	} else {
564 	  // return true if y is +qNaN and x is +sNaN
565 	  // (we know they're different bc of xor if_stmt above)
566 	  res = ((x & MASK_SNAN) == MASK_SNAN);
567 	  BID_RETURN (res);
568 	}
569       }
570     }
571   } else if ((y & MASK_NAN) == MASK_NAN) {
572     // x is certainly not NAN in this case.
573     // return true if y is positive
574     res = ((y & MASK_SIGN) != MASK_SIGN);
575     BID_RETURN (res);
576   }
577   // SIMPLE (CASE2)
578   // if all the bits are the same, these numbers are equal.
579   if (x == y) {
580     res = 1;
581     BID_RETURN (res);
582   }
583   // OPPOSITE SIGNS (CASE 3)
584   // if signs are opposite, return 1 if x is negative
585   // (if x<y, totalOrder is true)
586   if (((x & MASK_SIGN) == MASK_SIGN) ^ ((y & MASK_SIGN) == MASK_SIGN)) {
587     res = (x & MASK_SIGN) == MASK_SIGN;
588     BID_RETURN (res);
589   }
590   // INFINITY (CASE4)
591   if ((x & MASK_INF) == MASK_INF) {
592     // if x==neg_inf, return (y == neg_inf)?1:0;
593     if ((x & MASK_SIGN) == MASK_SIGN) {
594       res = 1;
595       BID_RETURN (res);
596     } else {
597       // x is positive infinity, only return1 if y
598       // is positive infinity as well
599       // (we know y has same sign as x)
600       res = ((y & MASK_INF) == MASK_INF);
601       BID_RETURN (res);
602     }
603   } else if ((y & MASK_INF) == MASK_INF) {
604     // x is finite, so:
605     //    if y is +inf, x<y
606     //    if y is -inf, x>y
607     res = ((y & MASK_SIGN) != MASK_SIGN);
608     BID_RETURN (res);
609   }
610   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
611   if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
612     exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
613     sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
614     if (sig_x > 9999999999999999ull || sig_x == 0) {
615       x_is_zero = 1;
616     }
617   } else {
618     exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
619     sig_x = (x & MASK_BINARY_SIG1);
620     if (sig_x == 0) {
621       x_is_zero = 1;
622     }
623   }
624 
625   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
626   if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
627     exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
628     sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
629     if (sig_y > 9999999999999999ull || sig_y == 0) {
630       y_is_zero = 1;
631     }
632   } else {
633     exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
634     sig_y = (y & MASK_BINARY_SIG1);
635     if (sig_y == 0) {
636       y_is_zero = 1;
637     }
638   }
639 
640   // ZERO (CASE 5)
641   // if x and y represent the same entities, and
642   // both are negative , return true iff exp_x <= exp_y
643   if (x_is_zero && y_is_zero) {
644     if (!((x & MASK_SIGN) == MASK_SIGN) ^
645 	((y & MASK_SIGN) == MASK_SIGN)) {
646       // if signs are the same:
647       // totalOrder(x,y) iff exp_x >= exp_y for negative numbers
648       // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
649       if (exp_x == exp_y) {
650 	res = 1;
651 	BID_RETURN (res);
652       }
653       res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
654       BID_RETURN (res);
655     } else {
656       // signs are different.
657       // totalOrder(-0, +0) is true
658       // totalOrder(+0, -0) is false
659       res = ((x & MASK_SIGN) == MASK_SIGN);
660       BID_RETURN (res);
661     }
662   }
663   // if x is zero and y isn't, clearly x has the smaller payload.
664   if (x_is_zero) {
665     res = ((y & MASK_SIGN) != MASK_SIGN);
666     BID_RETURN (res);
667   }
668   // if y is zero, and x isn't, clearly y has the smaller payload.
669   if (y_is_zero) {
670     res = ((x & MASK_SIGN) == MASK_SIGN);
671     BID_RETURN (res);
672   }
673   // REDUNDANT REPRESENTATIONS (CASE6)
674   // if both components are either bigger or smaller,
675   // it is clear what needs to be done
676   if (sig_x > sig_y && exp_x >= exp_y) {
677     res = ((x & MASK_SIGN) == MASK_SIGN);
678     BID_RETURN (res);
679   }
680   if (sig_x < sig_y && exp_x <= exp_y) {
681     res = ((x & MASK_SIGN) != MASK_SIGN);
682     BID_RETURN (res);
683   }
684   // if exp_x is 15 greater than exp_y, it is
685   // definitely larger, so no need for compensation
686   if (exp_x - exp_y > 15) {
687     // difference cannot be greater than 10^15
688     res = ((x & MASK_SIGN) == MASK_SIGN);
689     BID_RETURN (res);
690   }
691   // if exp_x is 15 less than exp_y, it is
692   // definitely smaller, no need for compensation
693   if (exp_y - exp_x > 15) {
694     res = ((x & MASK_SIGN) != MASK_SIGN);
695     BID_RETURN (res);
696   }
697   // if |exp_x - exp_y| < 15, it comes down
698   // to the compensated significand
699   if (exp_x > exp_y) {
700     // otherwise adjust the x significand upwards
701     __mul_64x64_to_128MACH (sig_n_prime, sig_x,
702 			    mult_factor[exp_x - exp_y]);
703     // if x and y represent the same entities,
704     // and both are negative, return true iff exp_x <= exp_y
705     if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
706       // case cannot occure, because all bits must
707       // be the same - would have been caught if (x==y)
708       res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
709       BID_RETURN (res);
710     }
711     // if positive, return 1 if adjusted x is smaller than y
712     res = ((sig_n_prime.w[1] == 0)
713 	   && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) ==
714 					   MASK_SIGN);
715     BID_RETURN (res);
716   }
717   // adjust the y significand upwards
718   __mul_64x64_to_128MACH (sig_n_prime, sig_y,
719 			  mult_factor[exp_y - exp_x]);
720 
721   // if x and y represent the same entities,
722   // and both are negative, return true iff exp_x <= exp_y
723   if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
724     // Cannot occur, because all bits must be the same.
725     // Case would have been caught if (x==y)
726     res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
727     BID_RETURN (res);
728   }
729   // values are not equal, for positive numbers return 1
730   // if x is less than y.  0 otherwise
731   res = ((sig_n_prime.w[1] > 0)
732 	 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
733 					   MASK_SIGN);
734   BID_RETURN (res);
735 }
736 
737 // totalOrderMag is TotalOrder(abs(x), abs(y))
738 #if DECIMAL_CALL_BY_REFERENCE
739 void
740 bid64_totalOrderMag (int *pres, UINT64 * px,
741 		     UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
742   UINT64 x = *px;
743   UINT64 y = *py;
744 #else
745 int
746 bid64_totalOrderMag (UINT64 x,
747 		     UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
748 #endif
749   int res;
750   int exp_x, exp_y;
751   UINT64 sig_x, sig_y, pyld_y, pyld_x;
752   UINT128 sig_n_prime;
753   char x_is_zero = 0, y_is_zero = 0;
754 
755   // NaN (CASE 1)
756   // if x and y are unordered numerically because either operand is NaN
757   //    (1) totalOrder(number, +NaN) is true
758   //    (2) if x and y are both NaN:
759   //       i) signaling < quiet for +NaN
760   //       ii) lesser payload < greater payload for +NaN
761   //       iii) else if bitwise identical (in canonical form), return 1
762   if ((x & MASK_NAN) == MASK_NAN) {
763     // x is +NaN
764 
765     // return false, unless y is +NaN also
766     if ((y & MASK_NAN) != MASK_NAN) {
767       res = 0;	// y is a number, return 1
768       BID_RETURN (res);
769 
770     } else {
771 
772       // x and y are both +NaN;
773       // must investigate payload if both quiet or both signaling
774       // this xnor statement will be true if both x and y are +qNaN or +sNaN
775       if (!
776 	  (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
777 					     MASK_SNAN))) {
778 	// it comes down to the payload.  we want to return true if x has a
779 	// smaller payload, or if the payloads are equal (canonical forms
780 	// are bitwise identical)
781 	pyld_y = y & 0x0003ffffffffffffull;
782 	pyld_x = x & 0x0003ffffffffffffull;
783 	// if x is zero and y isn't, x has the smaller
784 	// payload definitely (since we know y isn't 0 at this point)
785 	if (pyld_x > 999999999999999ull || pyld_x == 0) {
786 	  res = 1;
787 	  BID_RETURN (res);
788 	}
789 
790 	if (pyld_y > 999999999999999ull || pyld_y == 0) {
791 	  // if y is zero, x must be less than or numerically equal
792 	  res = 0;
793 	  BID_RETURN (res);
794 	}
795 	res = (pyld_x <= pyld_y);
796 	BID_RETURN (res);
797 
798       } else {
799 	// return true if y is +qNaN and x is +sNaN
800 	// (we know they're different bc of xor if_stmt above)
801 	res = ((x & MASK_SNAN) == MASK_SNAN);
802 	BID_RETURN (res);
803       }
804     }
805 
806   } else if ((y & MASK_NAN) == MASK_NAN) {
807     // x is certainly not NAN in this case.
808     // return true if y is positive
809     res = 1;
810     BID_RETURN (res);
811   }
812   // SIMPLE (CASE2)
813   // if all the bits (except sign bit) are the same,
814   // these numbers are equal.
815   if ((x & ~MASK_SIGN) == (y & ~MASK_SIGN)) {
816     res = 1;
817     BID_RETURN (res);
818   }
819   // INFINITY (CASE3)
820   if ((x & MASK_INF) == MASK_INF) {
821     // x is positive infinity, only return1
822     // if y is positive infinity as well
823     res = ((y & MASK_INF) == MASK_INF);
824     BID_RETURN (res);
825   } else if ((y & MASK_INF) == MASK_INF) {
826     // x is finite, so:
827     //    if y is +inf, x<y
828     res = 1;
829     BID_RETURN (res);
830   }
831   // if steering bits are 11 (condition will be 0),
832   // then exponent is G[0:w+1] =>
833   if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
834     exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
835     sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
836     if (sig_x > 9999999999999999ull || sig_x == 0) {
837       x_is_zero = 1;
838     }
839   } else {
840     exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
841     sig_x = (x & MASK_BINARY_SIG1);
842     if (sig_x == 0) {
843       x_is_zero = 1;
844     }
845   }
846 
847   // if steering bits are 11 (condition will be 0),
848   // then exponent is G[0:w+1] =>
849   if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
850     exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
851     sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
852     if (sig_y > 9999999999999999ull || sig_y == 0) {
853       y_is_zero = 1;
854     }
855   } else {
856     exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
857     sig_y = (y & MASK_BINARY_SIG1);
858     if (sig_y == 0) {
859       y_is_zero = 1;
860     }
861   }
862 
863   // ZERO (CASE 5)
864   // if x and y represent the same entities,
865   // and both are negative , return true iff exp_x <= exp_y
866   if (x_is_zero && y_is_zero) {
867     // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
868     res = (exp_x <= exp_y);
869     BID_RETURN (res);
870   }
871   // if x is zero and y isn't, clearly x has the smaller payload.
872   if (x_is_zero) {
873     res = 1;
874     BID_RETURN (res);
875   }
876   // if y is zero, and x isn't, clearly y has the smaller payload.
877   if (y_is_zero) {
878     res = 0;
879     BID_RETURN (res);
880   }
881   // REDUNDANT REPRESENTATIONS (CASE6)
882   // if both components are either bigger or smaller
883   if (sig_x > sig_y && exp_x >= exp_y) {
884     res = 0;
885     BID_RETURN (res);
886   }
887   if (sig_x < sig_y && exp_x <= exp_y) {
888     res = 1;
889     BID_RETURN (res);
890   }
891   // if exp_x is 15 greater than exp_y, it is definitely
892   // larger, so no need for compensation
893   if (exp_x - exp_y > 15) {
894     res = 0;	// difference cannot be greater than 10^15
895     BID_RETURN (res);
896   }
897   // if exp_x is 15 less than exp_y, it is definitely
898   // smaller, no need for compensation
899   if (exp_y - exp_x > 15) {
900     res = 1;
901     BID_RETURN (res);
902   }
903   // if |exp_x - exp_y| < 15, it comes down
904   // to the compensated significand
905   if (exp_x > exp_y) {
906 
907     // otherwise adjust the x significand upwards
908     __mul_64x64_to_128MACH (sig_n_prime, sig_x,
909 			    mult_factor[exp_x - exp_y]);
910 
911     // if x and y represent the same entities,
912     // and both are negative, return true iff exp_x <= exp_y
913     if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
914       // case cannot occur, because all bits
915       // must be the same - would have been caught if (x==y)
916       res = (exp_x <= exp_y);
917       BID_RETURN (res);
918     }
919     // if positive, return 1 if adjusted x is smaller than y
920     res = ((sig_n_prime.w[1] == 0) && sig_n_prime.w[0] < sig_y);
921     BID_RETURN (res);
922   }
923   // adjust the y significand upwards
924   __mul_64x64_to_128MACH (sig_n_prime, sig_y,
925 			  mult_factor[exp_y - exp_x]);
926 
927   // if x and y represent the same entities,
928   // and both are negative, return true iff exp_x <= exp_y
929   if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
930     res = (exp_x <= exp_y);
931     BID_RETURN (res);
932   }
933   // values are not equal, for positive numbers
934   // return 1 if x is less than y.  0 otherwise
935   res = ((sig_n_prime.w[1] > 0) || (sig_x < sig_n_prime.w[0]));
936   BID_RETURN (res);
937 
938 }
939 
940 #if DECIMAL_CALL_BY_REFERENCE
941 void
942 bid64_radix (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
943   UINT64 x = *px;
944 #else
945 int
946 bid64_radix (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
947 #endif
948   int res;
949   if (x)	// dummy test
950     res = 10;
951   else
952     res = 10;
953   BID_RETURN (res);
954 }
955