(root)/
gcc-13.2.0/
libgcc/
config/
libbid/
bid64_noncomp.c
       1  /* Copyright (C) 2007-2023 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
      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  }