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