OSDN Git Service

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