Home | History | Annotate | Line # | Download | only in libbid
      1  1.12  mrg /* Copyright (C) 2007-2022 Free Software Foundation, Inc.
      2   1.1  mrg 
      3   1.1  mrg This file is part of GCC.
      4   1.1  mrg 
      5   1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      6   1.1  mrg the terms of the GNU General Public License as published by the Free
      7   1.1  mrg Software Foundation; either version 3, or (at your option) any later
      8   1.1  mrg version.
      9   1.1  mrg 
     10   1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     11   1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     12   1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     13   1.1  mrg for more details.
     14   1.1  mrg 
     15   1.1  mrg Under Section 7 of GPL version 3, you are granted additional
     16   1.1  mrg permissions described in the GCC Runtime Library Exception, version
     17   1.1  mrg 3.1, as published by the Free Software Foundation.
     18   1.1  mrg 
     19   1.1  mrg You should have received a copy of the GNU General Public License and
     20   1.1  mrg a copy of the GCC Runtime Library Exception along with this program;
     21   1.1  mrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     22   1.1  mrg <http://www.gnu.org/licenses/>.  */
     23   1.1  mrg 
     24   1.1  mrg #define BID_128RES
     25   1.1  mrg #include "bid_internal.h"
     26   1.1  mrg 
     27   1.1  mrg /*****************************************************************************
     28   1.1  mrg  *  BID128 nextup
     29   1.1  mrg  ****************************************************************************/
     30   1.1  mrg 
     31   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
     32   1.1  mrg void
     33   1.1  mrg bid128_nextup (UINT128 * pres,
     34   1.1  mrg 	       UINT128 *
     35   1.1  mrg 	       px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
     36   1.1  mrg   UINT128 x = *px;
     37   1.1  mrg #else
     38   1.1  mrg UINT128
     39   1.1  mrg bid128_nextup (UINT128 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     40   1.1  mrg 	       _EXC_INFO_PARAM) {
     41   1.1  mrg #endif
     42   1.1  mrg 
     43   1.1  mrg   UINT128 res;
     44   1.1  mrg   UINT64 x_sign;
     45   1.1  mrg   UINT64 x_exp;
     46   1.1  mrg   int exp;
     47   1.1  mrg   BID_UI64DOUBLE tmp1;
     48   1.1  mrg   int x_nr_bits;
     49   1.1  mrg   int q1, ind;
     50   1.1  mrg   UINT128 C1;			// C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (UINT64)
     51   1.1  mrg 
     52   1.1  mrg   BID_SWAP128 (x);
     53   1.1  mrg   // unpack the argument
     54   1.1  mrg   x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
     55   1.1  mrg   C1.w[1] = x.w[1] & MASK_COEFF;
     56   1.1  mrg   C1.w[0] = x.w[0];
     57   1.1  mrg 
     58   1.1  mrg   // check for NaN or Infinity
     59   1.1  mrg   if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
     60   1.1  mrg     // x is special
     61   1.1  mrg     if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
     62   1.1  mrg       // if x = NaN, then res = Q (x)
     63   1.1  mrg       // check first for non-canonical NaN payload
     64   1.1  mrg       if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
     65   1.1  mrg 	  (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
     66   1.1  mrg 	   && (x.w[0] > 0x38c15b09ffffffffull))) {
     67   1.1  mrg 	x.w[1] = x.w[1] & 0xffffc00000000000ull;
     68   1.1  mrg 	x.w[0] = 0x0ull;
     69   1.1  mrg       }
     70   1.1  mrg       if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
     71   1.1  mrg 	// set invalid flag
     72   1.1  mrg 	*pfpsf |= INVALID_EXCEPTION;
     73   1.1  mrg 	// return quiet (x)
     74   1.1  mrg 	res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out also G[6]-G[16]
     75   1.1  mrg 	res.w[0] = x.w[0];
     76   1.1  mrg       } else {	// x is QNaN
     77   1.1  mrg 	// return x
     78   1.1  mrg 	res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out G[6]-G[16]
     79   1.1  mrg 	res.w[0] = x.w[0];
     80   1.1  mrg       }
     81   1.1  mrg     } else {	// x is not NaN, so it must be infinity
     82   1.1  mrg       if (!x_sign) {	// x is +inf
     83   1.1  mrg 	res.w[1] = 0x7800000000000000ull;	// +inf
     84   1.1  mrg 	res.w[0] = 0x0000000000000000ull;
     85   1.1  mrg       } else {	// x is -inf
     86   1.1  mrg 	res.w[1] = 0xdfffed09bead87c0ull;	// -MAXFP = -999...99 * 10^emax
     87   1.1  mrg 	res.w[0] = 0x378d8e63ffffffffull;
     88   1.1  mrg       }
     89   1.1  mrg     }
     90   1.1  mrg     BID_RETURN (res);
     91   1.1  mrg   }
     92   1.1  mrg   // check for non-canonical values (treated as zero)
     93   1.1  mrg   if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {	// G0_G1=11
     94   1.1  mrg     // non-canonical
     95   1.1  mrg     x_exp = (x.w[1] << 2) & MASK_EXP;	// biased and shifted left 49 bits
     96   1.1  mrg     C1.w[1] = 0;	// significand high
     97   1.1  mrg     C1.w[0] = 0;	// significand low
     98   1.1  mrg   } else {	// G0_G1 != 11
     99   1.1  mrg     x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bits
    100   1.1  mrg     if (C1.w[1] > 0x0001ed09bead87c0ull ||
    101   1.1  mrg 	(C1.w[1] == 0x0001ed09bead87c0ull
    102   1.1  mrg 	 && C1.w[0] > 0x378d8e63ffffffffull)) {
    103   1.1  mrg       // x is non-canonical if coefficient is larger than 10^34 -1
    104   1.1  mrg       C1.w[1] = 0;
    105   1.1  mrg       C1.w[0] = 0;
    106   1.1  mrg     } else {	// canonical
    107   1.1  mrg       ;
    108   1.1  mrg     }
    109   1.1  mrg   }
    110   1.1  mrg 
    111   1.1  mrg   if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    112   1.1  mrg     // x is +/-0
    113   1.1  mrg     res.w[1] = 0x0000000000000000ull;	// +1 * 10^emin
    114   1.1  mrg     res.w[0] = 0x0000000000000001ull;
    115   1.1  mrg   } else {	// x is not special and is not zero
    116   1.1  mrg     if (x.w[1] == 0x5fffed09bead87c0ull
    117   1.1  mrg 	&& x.w[0] == 0x378d8e63ffffffffull) {
    118   1.1  mrg       // x = +MAXFP = 999...99 * 10^emax
    119   1.1  mrg       res.w[1] = 0x7800000000000000ull;	// +inf
    120   1.1  mrg       res.w[0] = 0x0000000000000000ull;
    121   1.1  mrg     } else if (x.w[1] == 0x8000000000000000ull
    122   1.1  mrg 	       && x.w[0] == 0x0000000000000001ull) {
    123   1.1  mrg       // x = -MINFP = 1...99 * 10^emin
    124   1.1  mrg       res.w[1] = 0x8000000000000000ull;	// -0
    125   1.1  mrg       res.w[0] = 0x0000000000000000ull;
    126   1.1  mrg     } else {	// -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
    127   1.1  mrg       // can add/subtract 1 ulp to the significand
    128   1.1  mrg 
    129   1.1  mrg       // Note: we could check here if x >= 10^34 to speed up the case q1 = 34
    130   1.1  mrg       // q1 = nr. of decimal digits in x
    131   1.1  mrg       // determine first the nr. of bits in x
    132   1.1  mrg       if (C1.w[1] == 0) {
    133   1.1  mrg 	if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    134   1.1  mrg 	  // split the 64-bit value in two 32-bit halves to avoid rnd errors
    135   1.1  mrg 	  if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    136   1.1  mrg 	    tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    137   1.1  mrg 	    x_nr_bits =
    138   1.1  mrg 	      33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
    139   1.1  mrg 		    0x3ff);
    140   1.1  mrg 	  } else {	// x < 2^32
    141   1.1  mrg 	    tmp1.d = (double) (C1.w[0]);	// exact conversion
    142   1.1  mrg 	    x_nr_bits =
    143   1.1  mrg 	      1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
    144   1.1  mrg 		   0x3ff);
    145   1.1  mrg 	  }
    146   1.1  mrg 	} else {	// if x < 2^53
    147   1.1  mrg 	  tmp1.d = (double) C1.w[0];	// exact conversion
    148   1.1  mrg 	  x_nr_bits =
    149   1.1  mrg 	    1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    150   1.1  mrg 	}
    151   1.1  mrg       } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    152   1.1  mrg 	tmp1.d = (double) C1.w[1];	// exact conversion
    153   1.1  mrg 	x_nr_bits =
    154   1.1  mrg 	  65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    155   1.1  mrg       }
    156   1.1  mrg       q1 = nr_digits[x_nr_bits - 1].digits;
    157   1.1  mrg       if (q1 == 0) {
    158   1.1  mrg 	q1 = nr_digits[x_nr_bits - 1].digits1;
    159   1.1  mrg 	if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
    160   1.1  mrg 	    || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
    161   1.1  mrg 		&& C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    162   1.1  mrg 	  q1++;
    163   1.1  mrg       }
    164   1.1  mrg       // if q1 < P34 then pad the significand with zeros
    165   1.1  mrg       if (q1 < P34) {
    166   1.1  mrg 	exp = (x_exp >> 49) - 6176;
    167   1.1  mrg 	if (exp + 6176 > P34 - q1) {
    168   1.1  mrg 	  ind = P34 - q1;	// 1 <= ind <= P34 - 1
    169   1.1  mrg 	  // pad with P34 - q1 zeros, until exponent = emin
    170   1.1  mrg 	  // C1 = C1 * 10^ind
    171   1.1  mrg 	  if (q1 <= 19) {	// 64-bit C1
    172   1.1  mrg 	    if (ind <= 19) {	// 64-bit 10^ind and 64-bit C1
    173   1.1  mrg 	      __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
    174   1.1  mrg 	    } else {	// 128-bit 10^ind and 64-bit C1
    175   1.1  mrg 	      __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
    176   1.1  mrg 	    }
    177   1.1  mrg 	  } else {	// C1 is (most likely) 128-bit
    178   1.1  mrg 	    if (ind <= 14) {	// 64-bit 10^ind and 128-bit C1 (most likely)
    179   1.1  mrg 	      __mul_128x64_to_128 (C1, ten2k64[ind], C1);
    180   1.1  mrg 	    } else if (ind <= 19) {	// 64-bit 10^ind and 64-bit C1 (q1 <= 19)
    181   1.1  mrg 	      __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
    182   1.1  mrg 	    } else {	// 128-bit 10^ind and 64-bit C1 (C1 must be 64-bit)
    183   1.1  mrg 	      __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
    184   1.1  mrg 	    }
    185   1.1  mrg 	  }
    186   1.1  mrg 	  x_exp = x_exp - ((UINT64) ind << 49);
    187   1.1  mrg 	} else {	// pad with zeros until the exponent reaches emin
    188   1.1  mrg 	  ind = exp + 6176;
    189   1.1  mrg 	  // C1 = C1 * 10^ind
    190   1.1  mrg 	  if (ind <= 19) {	// 1 <= P34 - q1 <= 19 <=> 15 <= q1 <= 33
    191   1.1  mrg 	    if (q1 <= 19) {	// 64-bit C1, 64-bit 10^ind
    192   1.1  mrg 	      __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
    193   1.1  mrg 	    } else {	// 20 <= q1 <= 33 => 128-bit C1, 64-bit 10^ind
    194   1.1  mrg 	      __mul_128x64_to_128 (C1, ten2k64[ind], C1);
    195   1.1  mrg 	    }
    196   1.1  mrg 	  } else {	// if 20 <= P34 - q1 <= 33 <=> 1 <= q1 <= 14 =>
    197   1.1  mrg 	    // 64-bit C1, 128-bit 10^ind
    198   1.1  mrg 	    __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
    199   1.1  mrg 	  }
    200   1.1  mrg 	  x_exp = EXP_MIN;
    201   1.1  mrg 	}
    202   1.1  mrg       }
    203   1.1  mrg       if (!x_sign) {	// x > 0
    204   1.1  mrg 	// add 1 ulp (add 1 to the significand)
    205   1.1  mrg 	C1.w[0]++;
    206   1.1  mrg 	if (C1.w[0] == 0)
    207   1.1  mrg 	  C1.w[1]++;
    208   1.1  mrg 	if (C1.w[1] == 0x0001ed09bead87c0ull && C1.w[0] == 0x378d8e6400000000ull) {	// if  C1 = 10^34
    209   1.1  mrg 	  C1.w[1] = 0x0000314dc6448d93ull;	// C1 = 10^33
    210   1.1  mrg 	  C1.w[0] = 0x38c15b0a00000000ull;
    211   1.1  mrg 	  x_exp = x_exp + EXP_P1;
    212   1.1  mrg 	}
    213   1.1  mrg       } else {	// x < 0
    214   1.1  mrg 	// subtract 1 ulp (subtract 1 from the significand)
    215   1.1  mrg 	C1.w[0]--;
    216   1.1  mrg 	if (C1.w[0] == 0xffffffffffffffffull)
    217   1.1  mrg 	  C1.w[1]--;
    218   1.1  mrg 	if (x_exp != 0 && C1.w[1] == 0x0000314dc6448d93ull && C1.w[0] == 0x38c15b09ffffffffull) {	// if  C1 = 10^33 - 1
    219   1.1  mrg 	  C1.w[1] = 0x0001ed09bead87c0ull;	// C1 = 10^34 - 1
    220   1.1  mrg 	  C1.w[0] = 0x378d8e63ffffffffull;
    221   1.1  mrg 	  x_exp = x_exp - EXP_P1;
    222   1.1  mrg 	}
    223   1.1  mrg       }
    224   1.1  mrg       // assemble the result
    225   1.1  mrg       res.w[1] = x_sign | x_exp | C1.w[1];
    226   1.1  mrg       res.w[0] = C1.w[0];
    227   1.1  mrg     }	// end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
    228   1.1  mrg   }	// end x is not special and is not zero
    229   1.1  mrg   BID_RETURN (res);
    230   1.1  mrg }
    231   1.1  mrg 
    232   1.1  mrg /*****************************************************************************
    233   1.1  mrg  *  BID128 nextdown
    234   1.1  mrg  ****************************************************************************/
    235   1.1  mrg 
    236   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
    237   1.1  mrg void
    238   1.1  mrg bid128_nextdown (UINT128 * pres,
    239   1.1  mrg 		 UINT128 *
    240   1.1  mrg 		 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
    241   1.1  mrg   UINT128 x = *px;
    242   1.1  mrg #else
    243   1.1  mrg UINT128
    244   1.1  mrg bid128_nextdown (UINT128 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
    245   1.1  mrg 		 _EXC_INFO_PARAM) {
    246   1.1  mrg #endif
    247   1.1  mrg 
    248   1.1  mrg   UINT128 res;
    249   1.1  mrg   UINT64 x_sign;
    250   1.1  mrg   UINT64 x_exp;
    251   1.1  mrg   int exp;
    252   1.1  mrg   BID_UI64DOUBLE tmp1;
    253   1.1  mrg   int x_nr_bits;
    254   1.1  mrg   int q1, ind;
    255   1.1  mrg   UINT128 C1;			// C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (UINT64)
    256   1.1  mrg 
    257   1.1  mrg   BID_SWAP128 (x);
    258   1.1  mrg   // unpack the argument
    259   1.1  mrg   x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    260   1.1  mrg   C1.w[1] = x.w[1] & MASK_COEFF;
    261   1.1  mrg   C1.w[0] = x.w[0];
    262   1.1  mrg 
    263   1.1  mrg   // check for NaN or Infinity
    264   1.1  mrg   if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    265   1.1  mrg     // x is special
    266   1.1  mrg     if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    267   1.1  mrg       // if x = NaN, then res = Q (x)
    268   1.1  mrg       // check first for non-canonical NaN payload
    269   1.1  mrg       if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
    270   1.1  mrg 	  (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
    271   1.1  mrg 	   && (x.w[0] > 0x38c15b09ffffffffull))) {
    272   1.1  mrg 	x.w[1] = x.w[1] & 0xffffc00000000000ull;
    273   1.1  mrg 	x.w[0] = 0x0ull;
    274   1.1  mrg       }
    275   1.1  mrg       if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    276   1.1  mrg 	// set invalid flag
    277   1.1  mrg 	*pfpsf |= INVALID_EXCEPTION;
    278   1.1  mrg 	// return quiet (x)
    279   1.1  mrg 	res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out also G[6]-G[16]
    280   1.1  mrg 	res.w[0] = x.w[0];
    281   1.1  mrg       } else {	// x is QNaN
    282   1.1  mrg 	// return x
    283   1.1  mrg 	res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out G[6]-G[16]
    284   1.1  mrg 	res.w[0] = x.w[0];
    285   1.1  mrg       }
    286   1.1  mrg     } else {	// x is not NaN, so it must be infinity
    287   1.1  mrg       if (!x_sign) {	// x is +inf
    288   1.1  mrg 	res.w[1] = 0x5fffed09bead87c0ull;	// +MAXFP = +999...99 * 10^emax
    289   1.1  mrg 	res.w[0] = 0x378d8e63ffffffffull;
    290   1.1  mrg       } else {	// x is -inf
    291   1.1  mrg 	res.w[1] = 0xf800000000000000ull;	// -inf
    292   1.1  mrg 	res.w[0] = 0x0000000000000000ull;
    293   1.1  mrg       }
    294   1.1  mrg     }
    295   1.1  mrg     BID_RETURN (res);
    296   1.1  mrg   }
    297   1.1  mrg   // check for non-canonical values (treated as zero)
    298   1.1  mrg   if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {	// G0_G1=11
    299   1.1  mrg     // non-canonical
    300   1.1  mrg     x_exp = (x.w[1] << 2) & MASK_EXP;	// biased and shifted left 49 bits
    301   1.1  mrg     C1.w[1] = 0;	// significand high
    302   1.1  mrg     C1.w[0] = 0;	// significand low
    303   1.1  mrg   } else {	// G0_G1 != 11
    304   1.1  mrg     x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bits
    305   1.1  mrg     if (C1.w[1] > 0x0001ed09bead87c0ull ||
    306   1.1  mrg 	(C1.w[1] == 0x0001ed09bead87c0ull
    307   1.1  mrg 	 && C1.w[0] > 0x378d8e63ffffffffull)) {
    308   1.1  mrg       // x is non-canonical if coefficient is larger than 10^34 -1
    309   1.1  mrg       C1.w[1] = 0;
    310   1.1  mrg       C1.w[0] = 0;
    311   1.1  mrg     } else {	// canonical
    312   1.1  mrg       ;
    313   1.1  mrg     }
    314   1.1  mrg   }
    315   1.1  mrg 
    316   1.1  mrg   if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    317   1.1  mrg     // x is +/-0
    318   1.1  mrg     res.w[1] = 0x8000000000000000ull;	// -1 * 10^emin
    319   1.1  mrg     res.w[0] = 0x0000000000000001ull;
    320   1.1  mrg   } else {	// x is not special and is not zero
    321   1.1  mrg     if (x.w[1] == 0xdfffed09bead87c0ull
    322   1.1  mrg 	&& x.w[0] == 0x378d8e63ffffffffull) {
    323   1.1  mrg       // x = -MAXFP = -999...99 * 10^emax
    324   1.1  mrg       res.w[1] = 0xf800000000000000ull;	// -inf
    325   1.1  mrg       res.w[0] = 0x0000000000000000ull;
    326   1.1  mrg     } else if (x.w[1] == 0x0ull && x.w[0] == 0x0000000000000001ull) {	// +MINFP
    327   1.1  mrg       res.w[1] = 0x0000000000000000ull;	// +0
    328   1.1  mrg       res.w[0] = 0x0000000000000000ull;
    329   1.1  mrg     } else {	// -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
    330   1.1  mrg       // can add/subtract 1 ulp to the significand
    331   1.1  mrg 
    332   1.1  mrg       // Note: we could check here if x >= 10^34 to speed up the case q1 = 34
    333   1.1  mrg       // q1 = nr. of decimal digits in x
    334   1.1  mrg       // determine first the nr. of bits in x
    335   1.1  mrg       if (C1.w[1] == 0) {
    336   1.1  mrg 	if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    337   1.1  mrg 	  // split the 64-bit value in two 32-bit halves to avoid rnd errors
    338   1.1  mrg 	  if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    339   1.1  mrg 	    tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    340   1.1  mrg 	    x_nr_bits =
    341   1.1  mrg 	      33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
    342   1.1  mrg 		    0x3ff);
    343   1.1  mrg 	  } else {	// x < 2^32
    344   1.1  mrg 	    tmp1.d = (double) (C1.w[0]);	// exact conversion
    345   1.1  mrg 	    x_nr_bits =
    346   1.1  mrg 	      1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
    347   1.1  mrg 		   0x3ff);
    348   1.1  mrg 	  }
    349   1.1  mrg 	} else {	// if x < 2^53
    350   1.1  mrg 	  tmp1.d = (double) C1.w[0];	// exact conversion
    351   1.1  mrg 	  x_nr_bits =
    352   1.1  mrg 	    1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    353   1.1  mrg 	}
    354   1.1  mrg       } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    355   1.1  mrg 	tmp1.d = (double) C1.w[1];	// exact conversion
    356   1.1  mrg 	x_nr_bits =
    357   1.1  mrg 	  65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    358   1.1  mrg       }
    359   1.1  mrg       q1 = nr_digits[x_nr_bits - 1].digits;
    360   1.1  mrg       if (q1 == 0) {
    361   1.1  mrg 	q1 = nr_digits[x_nr_bits - 1].digits1;
    362   1.1  mrg 	if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
    363   1.1  mrg 	    || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
    364   1.1  mrg 		&& C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    365   1.1  mrg 	  q1++;
    366   1.1  mrg       }
    367   1.1  mrg       // if q1 < P then pad the significand with zeros
    368   1.1  mrg       if (q1 < P34) {
    369   1.1  mrg 	exp = (x_exp >> 49) - 6176;
    370   1.1  mrg 	if (exp + 6176 > P34 - q1) {
    371   1.1  mrg 	  ind = P34 - q1;	// 1 <= ind <= P34 - 1
    372   1.1  mrg 	  // pad with P34 - q1 zeros, until exponent = emin
    373   1.1  mrg 	  // C1 = C1 * 10^ind
    374   1.1  mrg 	  if (q1 <= 19) {	// 64-bit C1
    375   1.1  mrg 	    if (ind <= 19) {	// 64-bit 10^ind and 64-bit C1
    376   1.1  mrg 	      __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
    377   1.1  mrg 	    } else {	// 128-bit 10^ind and 64-bit C1
    378   1.1  mrg 	      __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
    379   1.1  mrg 	    }
    380   1.1  mrg 	  } else {	// C1 is (most likely) 128-bit
    381   1.1  mrg 	    if (ind <= 14) {	// 64-bit 10^ind and 128-bit C1 (most likely)
    382   1.1  mrg 	      __mul_128x64_to_128 (C1, ten2k64[ind], C1);
    383   1.1  mrg 	    } else if (ind <= 19) {	// 64-bit 10^ind and 64-bit C1 (q1 <= 19)
    384   1.1  mrg 	      __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
    385   1.1  mrg 	    } else {	// 128-bit 10^ind and 64-bit C1 (C1 must be 64-bit)
    386   1.1  mrg 	      __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
    387   1.1  mrg 	    }
    388   1.1  mrg 	  }
    389   1.1  mrg 	  x_exp = x_exp - ((UINT64) ind << 49);
    390   1.1  mrg 	} else {	// pad with zeros until the exponent reaches emin
    391   1.1  mrg 	  ind = exp + 6176;
    392   1.1  mrg 	  // C1 = C1 * 10^ind
    393   1.1  mrg 	  if (ind <= 19) {	// 1 <= P34 - q1 <= 19 <=> 15 <= q1 <= 33
    394   1.1  mrg 	    if (q1 <= 19) {	// 64-bit C1, 64-bit 10^ind
    395   1.1  mrg 	      __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
    396   1.1  mrg 	    } else {	// 20 <= q1 <= 33 => 128-bit C1, 64-bit 10^ind
    397   1.1  mrg 	      __mul_128x64_to_128 (C1, ten2k64[ind], C1);
    398   1.1  mrg 	    }
    399   1.1  mrg 	  } else {	// if 20 <= P34 - q1 <= 33 <=> 1 <= q1 <= 14 =>
    400   1.1  mrg 	    // 64-bit C1, 128-bit 10^ind
    401   1.1  mrg 	    __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
    402   1.1  mrg 	  }
    403   1.1  mrg 	  x_exp = EXP_MIN;
    404   1.1  mrg 	}
    405   1.1  mrg       }
    406   1.1  mrg       if (x_sign) {	// x < 0
    407   1.1  mrg 	// add 1 ulp (add 1 to the significand)
    408   1.1  mrg 	C1.w[0]++;
    409   1.1  mrg 	if (C1.w[0] == 0)
    410   1.1  mrg 	  C1.w[1]++;
    411   1.1  mrg 	if (C1.w[1] == 0x0001ed09bead87c0ull && C1.w[0] == 0x378d8e6400000000ull) {	// if  C1 = 10^34
    412   1.1  mrg 	  C1.w[1] = 0x0000314dc6448d93ull;	// C1 = 10^33
    413   1.1  mrg 	  C1.w[0] = 0x38c15b0a00000000ull;
    414   1.1  mrg 	  x_exp = x_exp + EXP_P1;
    415   1.1  mrg 	}
    416   1.1  mrg       } else {	// x > 0
    417   1.1  mrg 	// subtract 1 ulp (subtract 1 from the significand)
    418   1.1  mrg 	C1.w[0]--;
    419   1.1  mrg 	if (C1.w[0] == 0xffffffffffffffffull)
    420   1.1  mrg 	  C1.w[1]--;
    421   1.1  mrg 	if (x_exp != 0 && C1.w[1] == 0x0000314dc6448d93ull && C1.w[0] == 0x38c15b09ffffffffull) {	// if  C1 = 10^33 - 1
    422   1.1  mrg 	  C1.w[1] = 0x0001ed09bead87c0ull;	// C1 = 10^34 - 1
    423   1.1  mrg 	  C1.w[0] = 0x378d8e63ffffffffull;
    424   1.1  mrg 	  x_exp = x_exp - EXP_P1;
    425   1.1  mrg 	}
    426   1.1  mrg       }
    427   1.1  mrg       // assemble the result
    428   1.1  mrg       res.w[1] = x_sign | x_exp | C1.w[1];
    429   1.1  mrg       res.w[0] = C1.w[0];
    430   1.1  mrg     }	// end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
    431   1.1  mrg   }	// end x is not special and is not zero
    432   1.1  mrg   BID_RETURN (res);
    433   1.1  mrg }
    434   1.1  mrg 
    435   1.1  mrg /*****************************************************************************
    436   1.1  mrg  *  BID128 nextafter
    437   1.1  mrg  ****************************************************************************/
    438   1.1  mrg 
    439   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
    440   1.1  mrg void
    441   1.1  mrg bid128_nextafter (UINT128 * pres, UINT128 * px,
    442   1.1  mrg 		  UINT128 *
    443   1.1  mrg 		  py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
    444   1.1  mrg {
    445   1.1  mrg   UINT128 x = *px;
    446   1.1  mrg   UINT128 y = *py;
    447   1.1  mrg   UINT128 xnswp = *px;
    448   1.1  mrg   UINT128 ynswp = *py;
    449   1.1  mrg #else
    450   1.1  mrg UINT128
    451   1.1  mrg bid128_nextafter (UINT128 x,
    452   1.1  mrg 		  UINT128 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
    453   1.1  mrg 		  _EXC_INFO_PARAM) {
    454   1.1  mrg   UINT128 xnswp = x;
    455   1.1  mrg   UINT128 ynswp = y;
    456   1.1  mrg #endif
    457   1.1  mrg 
    458   1.1  mrg   UINT128 res;
    459   1.1  mrg   UINT128 tmp1, tmp2, tmp3;
    460   1.1  mrg   FPSC tmp_fpsf = 0;		// dummy fpsf for calls to comparison functions
    461   1.1  mrg   int res1, res2;
    462   1.1  mrg   UINT64 x_exp;
    463   1.1  mrg 
    464   1.1  mrg 
    465   1.1  mrg   BID_SWAP128 (x);
    466   1.1  mrg   BID_SWAP128 (y);
    467   1.1  mrg   // check for NaNs
    468   1.1  mrg   if (((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL)
    469   1.1  mrg       || ((y.w[1] & MASK_SPECIAL) == MASK_SPECIAL)) {
    470   1.1  mrg     // x is special or y is special
    471   1.1  mrg     if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    472   1.1  mrg       // if x = NaN, then res = Q (x)
    473   1.1  mrg       // check first for non-canonical NaN payload
    474   1.1  mrg       if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
    475   1.1  mrg 	  (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
    476   1.1  mrg 	   && (x.w[0] > 0x38c15b09ffffffffull))) {
    477   1.1  mrg 	x.w[1] = x.w[1] & 0xffffc00000000000ull;
    478   1.1  mrg 	x.w[0] = 0x0ull;
    479   1.1  mrg       }
    480   1.1  mrg       if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    481   1.1  mrg 	// set invalid flag
    482   1.1  mrg 	*pfpsf |= INVALID_EXCEPTION;
    483   1.1  mrg 	// return quiet (x)
    484   1.1  mrg 	res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out also G[6]-G[16]
    485   1.1  mrg 	res.w[0] = x.w[0];
    486   1.1  mrg       } else {	// x is QNaN
    487   1.1  mrg 	// return x
    488   1.1  mrg 	res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out G[6]-G[16]
    489   1.1  mrg 	res.w[0] = x.w[0];
    490   1.1  mrg 	if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {	// y is SNAN
    491   1.1  mrg 	  // set invalid flag
    492   1.1  mrg 	  *pfpsf |= INVALID_EXCEPTION;
    493   1.1  mrg 	}
    494   1.1  mrg       }
    495   1.1  mrg       BID_RETURN (res)
    496   1.1  mrg     } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {	// y is NAN
    497   1.1  mrg       // if x = NaN, then res = Q (x)
    498   1.1  mrg       // check first for non-canonical NaN payload
    499   1.1  mrg       if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
    500   1.1  mrg 	  (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
    501   1.1  mrg 	   && (y.w[0] > 0x38c15b09ffffffffull))) {
    502   1.1  mrg 	y.w[1] = y.w[1] & 0xffffc00000000000ull;
    503   1.1  mrg 	y.w[0] = 0x0ull;
    504   1.1  mrg       }
    505   1.1  mrg       if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {	// y is SNAN
    506   1.1  mrg 	// set invalid flag
    507   1.1  mrg 	*pfpsf |= INVALID_EXCEPTION;
    508   1.1  mrg 	// return quiet (x)
    509   1.1  mrg 	res.w[1] = y.w[1] & 0xfc003fffffffffffull;	// clear out also G[6]-G[16]
    510   1.1  mrg 	res.w[0] = y.w[0];
    511   1.1  mrg       } else {	// x is QNaN
    512   1.1  mrg 	// return x
    513   1.1  mrg 	res.w[1] = y.w[1] & 0xfc003fffffffffffull;	// clear out G[6]-G[16]
    514   1.1  mrg 	res.w[0] = y.w[0];
    515   1.1  mrg       }
    516   1.1  mrg       BID_RETURN (res)
    517   1.1  mrg     } else {	// at least one is infinity
    518   1.1  mrg       if ((x.w[1] & MASK_ANY_INF) == MASK_INF) {	// x = inf
    519   1.1  mrg 	x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
    520   1.1  mrg 	x.w[0] = 0x0ull;
    521   1.1  mrg       }
    522   1.1  mrg       if ((y.w[1] & MASK_ANY_INF) == MASK_INF) {	// y = inf
    523   1.1  mrg 	y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
    524   1.1  mrg 	y.w[0] = 0x0ull;
    525   1.1  mrg       }
    526   1.1  mrg     }
    527   1.1  mrg   }
    528   1.1  mrg   // neither x nor y is NaN
    529   1.1  mrg 
    530   1.1  mrg   // if not infinity, check for non-canonical values x (treated as zero)
    531   1.1  mrg   if ((x.w[1] & MASK_ANY_INF) != MASK_INF) {	// x != inf
    532   1.1  mrg     if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {	// G0_G1=11
    533   1.1  mrg       // non-canonical
    534   1.1  mrg       x_exp = (x.w[1] << 2) & MASK_EXP;	// biased and shifted left 49 bits
    535   1.1  mrg       x.w[1] = (x.w[1] & MASK_SIGN) | x_exp;
    536   1.1  mrg       x.w[0] = 0x0ull;
    537   1.1  mrg     } else {	// G0_G1 != 11
    538   1.1  mrg       x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bits
    539   1.1  mrg       if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
    540   1.1  mrg 	  ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
    541   1.1  mrg 	   && x.w[0] > 0x378d8e63ffffffffull)) {
    542   1.1  mrg 	// x is non-canonical if coefficient is larger than 10^34 -1
    543   1.1  mrg 	x.w[1] = (x.w[1] & MASK_SIGN) | x_exp;
    544   1.1  mrg 	x.w[0] = 0x0ull;
    545   1.1  mrg       } else {	// canonical
    546   1.1  mrg 	;
    547   1.1  mrg       }
    548   1.1  mrg     }
    549   1.1  mrg   }
    550   1.1  mrg   // no need to check for non-canonical y
    551   1.1  mrg 
    552   1.1  mrg   // neither x nor y is NaN
    553   1.1  mrg   tmp_fpsf = *pfpsf;	// save fpsf
    554   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
    555   1.1  mrg   bid128_quiet_equal (&res1, &xnswp,
    556   1.1  mrg 		      &ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
    557   1.1  mrg 		      _EXC_INFO_ARG);
    558   1.1  mrg   bid128_quiet_greater (&res2, &xnswp,
    559   1.1  mrg 			&ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
    560   1.1  mrg 			_EXC_INFO_ARG);
    561   1.1  mrg #else
    562   1.1  mrg   res1 =
    563   1.1  mrg     bid128_quiet_equal (xnswp,
    564   1.1  mrg 			ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
    565   1.1  mrg 			_EXC_INFO_ARG);
    566   1.1  mrg   res2 =
    567   1.1  mrg     bid128_quiet_greater (xnswp,
    568   1.1  mrg 			  ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
    569   1.1  mrg 			  _EXC_INFO_ARG);
    570   1.1  mrg #endif
    571   1.1  mrg   *pfpsf = tmp_fpsf;	// restore fpsf
    572   1.1  mrg 
    573   1.1  mrg   if (res1) {	// x = y
    574   1.1  mrg     // return x with the sign of y
    575   1.1  mrg     res.w[1] =
    576   1.1  mrg       (x.w[1] & 0x7fffffffffffffffull) | (y.
    577   1.1  mrg 					  w[1] & 0x8000000000000000ull);
    578   1.1  mrg     res.w[0] = x.w[0];
    579   1.1  mrg   } else if (res2) {	// x > y
    580   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
    581   1.1  mrg     bid128_nextdown (&res,
    582   1.1  mrg 		     &xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
    583   1.1  mrg 		     _EXC_INFO_ARG);
    584   1.1  mrg #else
    585   1.1  mrg     res =
    586   1.1  mrg       bid128_nextdown (xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
    587   1.1  mrg 		       _EXC_INFO_ARG);
    588   1.1  mrg #endif
    589   1.1  mrg     BID_SWAP128 (res);
    590   1.1  mrg   } else {	// x < y
    591   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
    592   1.1  mrg     bid128_nextup (&res,
    593   1.1  mrg 		   &xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
    594   1.1  mrg #else
    595   1.1  mrg     res =
    596   1.1  mrg       bid128_nextup (xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
    597   1.1  mrg #endif
    598   1.1  mrg     BID_SWAP128 (res);
    599   1.1  mrg   }
    600   1.1  mrg   // if the operand x is finite but the result is infinite, signal
    601   1.1  mrg   // overflow and inexact
    602   1.1  mrg   if (((x.w[1] & MASK_SPECIAL) != MASK_SPECIAL)
    603   1.1  mrg       && ((res.w[1] & MASK_SPECIAL) == MASK_SPECIAL)) {
    604   1.1  mrg     // set the inexact flag
    605   1.1  mrg     *pfpsf |= INEXACT_EXCEPTION;
    606   1.1  mrg     // set the overflow flag
    607   1.1  mrg     *pfpsf |= OVERFLOW_EXCEPTION;
    608   1.1  mrg   }
    609   1.1  mrg   // if the result is in (-10^emin, 10^emin), and is different from the
    610   1.1  mrg   // operand x, signal underflow and inexact
    611   1.1  mrg   tmp1.w[HIGH_128W] = 0x0000314dc6448d93ull;
    612   1.1  mrg   tmp1.w[LOW_128W] = 0x38c15b0a00000000ull;	// +100...0[34] * 10^emin
    613   1.1  mrg   tmp2.w[HIGH_128W] = res.w[1] & 0x7fffffffffffffffull;
    614   1.1  mrg   tmp2.w[LOW_128W] = res.w[0];
    615   1.1  mrg   tmp3.w[HIGH_128W] = res.w[1];
    616   1.1  mrg   tmp3.w[LOW_128W] = res.w[0];
    617   1.1  mrg   tmp_fpsf = *pfpsf;	// save fpsf
    618   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
    619   1.1  mrg   bid128_quiet_greater (&res1, &tmp1,
    620   1.1  mrg 			&tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
    621   1.1  mrg 			_EXC_INFO_ARG);
    622   1.1  mrg   bid128_quiet_not_equal (&res2, &xnswp,
    623   1.1  mrg 			  &tmp3 _EXC_FLAGS_ARG _EXC_MASKS_ARG
    624   1.1  mrg 			  _EXC_INFO_ARG);
    625   1.1  mrg #else
    626   1.1  mrg   res1 =
    627   1.1  mrg     bid128_quiet_greater (tmp1,
    628   1.1  mrg 			  tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
    629   1.1  mrg 			  _EXC_INFO_ARG);
    630   1.1  mrg   res2 =
    631   1.1  mrg     bid128_quiet_not_equal (xnswp,
    632   1.1  mrg 			    tmp3 _EXC_FLAGS_ARG _EXC_MASKS_ARG
    633   1.1  mrg 			    _EXC_INFO_ARG);
    634   1.1  mrg #endif
    635   1.1  mrg   *pfpsf = tmp_fpsf;	// restore fpsf
    636   1.1  mrg   if (res1 && res2) {
    637   1.1  mrg     // set the inexact flag
    638   1.1  mrg     *pfpsf |= INEXACT_EXCEPTION;
    639   1.1  mrg     // set the underflow flag
    640   1.1  mrg     *pfpsf |= UNDERFLOW_EXCEPTION;
    641   1.1  mrg   }
    642   1.1  mrg   BID_RETURN (res);
    643   1.1  mrg }
    644