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 /***************************************************************************** 25 1.1 mrg * BID64 divide 26 1.1 mrg ***************************************************************************** 27 1.1 mrg * 28 1.1 mrg * Algorithm description: 29 1.1 mrg * 30 1.1 mrg * if(coefficient_x<coefficient_y) 31 1.1 mrg * p = number_digits(coefficient_y) - number_digits(coefficient_x) 32 1.1 mrg * A = coefficient_x*10^p 33 1.1 mrg * B = coefficient_y 34 1.1 mrg * CA= A*10^(15+j), j=0 for A>=B, 1 otherwise 35 1.1 mrg * Q = 0 36 1.1 mrg * else 37 1.1 mrg * get Q=(int)(coefficient_x/coefficient_y) 38 1.1 mrg * (based on double precision divide) 39 1.1 mrg * check for exact divide case 40 1.1 mrg * Let R = coefficient_x - Q*coefficient_y 41 1.1 mrg * Let m=16-number_digits(Q) 42 1.1 mrg * CA=R*10^m, Q=Q*10^m 43 1.1 mrg * B = coefficient_y 44 1.1 mrg * endif 45 1.1 mrg * if (CA<2^64) 46 1.1 mrg * Q += CA/B (64-bit unsigned divide) 47 1.1 mrg * else 48 1.1 mrg * get final Q using double precision divide, followed by 3 integer 49 1.1 mrg * iterations 50 1.1 mrg * if exact result, eliminate trailing zeros 51 1.1 mrg * check for underflow 52 1.1 mrg * round coefficient to nearest 53 1.1 mrg * 54 1.1 mrg ****************************************************************************/ 55 1.1 mrg 56 1.1 mrg #include "bid_internal.h" 57 1.1 mrg #include "bid_div_macros.h" 58 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 59 1.1 mrg #include <fenv.h> 60 1.1 mrg 61 1.1 mrg #define FE_ALL_FLAGS FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT 62 1.1 mrg #endif 63 1.1 mrg 64 1.1 mrg extern UINT32 convert_table[5][128][2]; 65 1.1 mrg extern SINT8 factors[][2]; 66 1.1 mrg extern UINT8 packed_10000_zeros[]; 67 1.1 mrg 68 1.1 mrg 69 1.1 mrg #if DECIMAL_CALL_BY_REFERENCE 70 1.1 mrg 71 1.1 mrg void 72 1.1 mrg bid64_div (UINT64 * pres, UINT64 * px, 73 1.1 mrg UINT64 * 74 1.1 mrg py _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM 75 1.1 mrg _EXC_INFO_PARAM) { 76 1.1 mrg UINT64 x, y; 77 1.1 mrg #else 78 1.1 mrg 79 1.1 mrg UINT64 80 1.1 mrg bid64_div (UINT64 x, 81 1.1 mrg UINT64 y _RND_MODE_PARAM _EXC_FLAGS_PARAM 82 1.1 mrg _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 83 1.1 mrg #endif 84 1.1 mrg UINT128 CA, CT; 85 1.1 mrg UINT64 sign_x, sign_y, coefficient_x, coefficient_y, A, B, QX, PD; 86 1.1 mrg UINT64 A2, Q, Q2, B2, B4, B5, R, T, DU, res; 87 1.1 mrg UINT64 valid_x, valid_y; 88 1.1 mrg SINT64 D; 89 1.1 mrg int_double t_scale, tempq, temp_b; 90 1.1 mrg int_float tempx, tempy; 91 1.1 mrg double da, db, dq, da_h, da_l; 92 1.1 mrg int exponent_x, exponent_y, bin_expon_cx; 93 1.1 mrg int diff_expon, ed1, ed2, bin_index; 94 1.1 mrg int rmode, amount; 95 1.1 mrg int nzeros, i, j, k, d5; 96 1.1 mrg UINT32 QX32, tdigit[3], digit, digit_h, digit_low; 97 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 98 1.1 mrg fexcept_t binaryflags = 0; 99 1.1 mrg #endif 100 1.1 mrg 101 1.1 mrg #if DECIMAL_CALL_BY_REFERENCE 102 1.1 mrg #if !DECIMAL_GLOBAL_ROUNDING 103 1.1 mrg _IDEC_round rnd_mode = *prnd_mode; 104 1.1 mrg #endif 105 1.1 mrg x = *px; 106 1.1 mrg y = *py; 107 1.1 mrg #endif 108 1.1 mrg 109 1.1 mrg valid_x = unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x); 110 1.1 mrg valid_y = unpack_BID64 (&sign_y, &exponent_y, &coefficient_y, y); 111 1.1 mrg 112 1.1 mrg // unpack arguments, check for NaN or Infinity 113 1.1 mrg if (!valid_x) { 114 1.1 mrg // x is Inf. or NaN 115 1.1 mrg #ifdef SET_STATUS_FLAGS 116 1.1 mrg if ((y & SNAN_MASK64) == SNAN_MASK64) // y is sNaN 117 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 118 1.1 mrg #endif 119 1.1 mrg 120 1.1 mrg // test if x is NaN 121 1.1 mrg if ((x & NAN_MASK64) == NAN_MASK64) { 122 1.1 mrg #ifdef SET_STATUS_FLAGS 123 1.1 mrg if ((x & SNAN_MASK64) == SNAN_MASK64) // sNaN 124 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 125 1.1 mrg #endif 126 1.1 mrg BID_RETURN (coefficient_x & QUIET_MASK64); 127 1.1 mrg } 128 1.1 mrg // x is Infinity? 129 1.1 mrg if ((x & INFINITY_MASK64) == INFINITY_MASK64) { 130 1.1 mrg // check if y is Inf or NaN 131 1.1 mrg if ((y & INFINITY_MASK64) == INFINITY_MASK64) { 132 1.1 mrg // y==Inf, return NaN 133 1.1 mrg if ((y & NAN_MASK64) == INFINITY_MASK64) { // Inf/Inf 134 1.1 mrg #ifdef SET_STATUS_FLAGS 135 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 136 1.1 mrg #endif 137 1.1 mrg BID_RETURN (NAN_MASK64); 138 1.1 mrg } 139 1.1 mrg } else { 140 1.1 mrg // otherwise return +/-Inf 141 1.1 mrg BID_RETURN (((x ^ y) & 0x8000000000000000ull) | 142 1.1 mrg INFINITY_MASK64); 143 1.1 mrg } 144 1.1 mrg } 145 1.1 mrg // x==0 146 1.1 mrg if (((y & INFINITY_MASK64) != INFINITY_MASK64) 147 1.1 mrg && !(coefficient_y)) { 148 1.1 mrg // y==0 , return NaN 149 1.1 mrg #ifdef SET_STATUS_FLAGS 150 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 151 1.1 mrg #endif 152 1.1 mrg BID_RETURN (NAN_MASK64); 153 1.1 mrg } 154 1.1 mrg if (((y & INFINITY_MASK64) != INFINITY_MASK64)) { 155 1.1 mrg if ((y & SPECIAL_ENCODING_MASK64) == SPECIAL_ENCODING_MASK64) 156 1.1 mrg exponent_y = ((UINT32) (y >> 51)) & 0x3ff; 157 1.1 mrg else 158 1.1 mrg exponent_y = ((UINT32) (y >> 53)) & 0x3ff; 159 1.1 mrg sign_y = y & 0x8000000000000000ull; 160 1.1 mrg 161 1.1 mrg exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS; 162 1.1 mrg if (exponent_x > DECIMAL_MAX_EXPON_64) 163 1.1 mrg exponent_x = DECIMAL_MAX_EXPON_64; 164 1.1 mrg else if (exponent_x < 0) 165 1.1 mrg exponent_x = 0; 166 1.1 mrg BID_RETURN ((sign_x ^ sign_y) | (((UINT64) exponent_x) << 53)); 167 1.1 mrg } 168 1.1 mrg 169 1.1 mrg } 170 1.1 mrg if (!valid_y) { 171 1.1 mrg // y is Inf. or NaN 172 1.1 mrg 173 1.1 mrg // test if y is NaN 174 1.1 mrg if ((y & NAN_MASK64) == NAN_MASK64) { 175 1.1 mrg #ifdef SET_STATUS_FLAGS 176 1.1 mrg if ((y & SNAN_MASK64) == SNAN_MASK64) // sNaN 177 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 178 1.1 mrg #endif 179 1.1 mrg BID_RETURN (coefficient_y & QUIET_MASK64); 180 1.1 mrg } 181 1.1 mrg // y is Infinity? 182 1.1 mrg if ((y & INFINITY_MASK64) == INFINITY_MASK64) { 183 1.1 mrg // return +/-0 184 1.1 mrg BID_RETURN (((x ^ y) & 0x8000000000000000ull)); 185 1.1 mrg } 186 1.1 mrg // y is 0 187 1.1 mrg #ifdef SET_STATUS_FLAGS 188 1.1 mrg __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION); 189 1.1 mrg #endif 190 1.1 mrg BID_RETURN ((sign_x ^ sign_y) | INFINITY_MASK64); 191 1.1 mrg } 192 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 193 1.1 mrg (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS); 194 1.1 mrg #endif 195 1.1 mrg diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS; 196 1.1 mrg 197 1.1 mrg if (coefficient_x < coefficient_y) { 198 1.1 mrg // get number of decimal digits for c_x, c_y 199 1.1 mrg 200 1.1 mrg //--- get number of bits in the coefficients of x and y --- 201 1.1 mrg tempx.d = (float) coefficient_x; 202 1.1 mrg tempy.d = (float) coefficient_y; 203 1.1 mrg bin_index = (tempy.i - tempx.i) >> 23; 204 1.1 mrg 205 1.1 mrg A = coefficient_x * power10_index_binexp[bin_index]; 206 1.1 mrg B = coefficient_y; 207 1.1 mrg 208 1.1 mrg temp_b.d = (double) B; 209 1.1 mrg 210 1.1 mrg // compare A, B 211 1.1 mrg DU = (A - B) >> 63; 212 1.1 mrg ed1 = 15 + (int) DU; 213 1.1 mrg ed2 = estimate_decimal_digits[bin_index] + ed1; 214 1.1 mrg T = power10_table_128[ed1].w[0]; 215 1.1 mrg __mul_64x64_to_128 (CA, A, T); 216 1.1 mrg 217 1.1 mrg Q = 0; 218 1.1 mrg diff_expon = diff_expon - ed2; 219 1.1 mrg 220 1.1 mrg // adjust double precision db, to ensure that later A/B - (int)(da/db) > -1 221 1.1 mrg if (coefficient_y < 0x0020000000000000ull) { 222 1.1 mrg temp_b.i += 1; 223 1.1 mrg db = temp_b.d; 224 1.1 mrg } else 225 1.1 mrg db = (double) (B + 2 + (B & 1)); 226 1.1 mrg 227 1.1 mrg } else { 228 1.1 mrg // get c_x/c_y 229 1.1 mrg 230 1.1 mrg // set last bit before conversion to DP 231 1.1 mrg A2 = coefficient_x | 1; 232 1.1 mrg da = (double) A2; 233 1.1 mrg 234 1.1 mrg db = (double) coefficient_y; 235 1.1 mrg 236 1.1 mrg tempq.d = da / db; 237 1.1 mrg Q = (UINT64) tempq.d; 238 1.1 mrg 239 1.1 mrg R = coefficient_x - coefficient_y * Q; 240 1.1 mrg 241 1.1 mrg // will use to get number of dec. digits of Q 242 1.1 mrg bin_expon_cx = (tempq.i >> 52) - 0x3ff; 243 1.1 mrg 244 1.1 mrg // R<0 ? 245 1.1 mrg D = ((SINT64) R) >> 63; 246 1.1 mrg Q += D; 247 1.1 mrg R += (coefficient_y & D); 248 1.1 mrg 249 1.1 mrg // exact result ? 250 1.1 mrg if (((SINT64) R) <= 0) { 251 1.1 mrg // can have R==-1 for coeff_y==1 252 1.1 mrg res = 253 1.1 mrg get_BID64 (sign_x ^ sign_y, diff_expon, (Q + R), rnd_mode, 254 1.1 mrg pfpsf); 255 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 256 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 257 1.1 mrg #endif 258 1.1 mrg BID_RETURN (res); 259 1.1 mrg } 260 1.1 mrg // get decimal digits of Q 261 1.1 mrg DU = power10_index_binexp[bin_expon_cx] - Q - 1; 262 1.1 mrg DU >>= 63; 263 1.1 mrg 264 1.1 mrg ed2 = 16 - estimate_decimal_digits[bin_expon_cx] - (int) DU; 265 1.1 mrg 266 1.1 mrg T = power10_table_128[ed2].w[0]; 267 1.1 mrg __mul_64x64_to_128 (CA, R, T); 268 1.1 mrg B = coefficient_y; 269 1.1 mrg 270 1.1 mrg Q *= power10_table_128[ed2].w[0]; 271 1.1 mrg diff_expon -= ed2; 272 1.1 mrg 273 1.1 mrg } 274 1.1 mrg 275 1.1 mrg if (!CA.w[1]) { 276 1.1 mrg Q2 = CA.w[0] / B; 277 1.1 mrg B2 = B + B; 278 1.1 mrg B4 = B2 + B2; 279 1.1 mrg R = CA.w[0] - Q2 * B; 280 1.1 mrg Q += Q2; 281 1.1 mrg } else { 282 1.1 mrg 283 1.1 mrg // 2^64 284 1.1 mrg t_scale.i = 0x43f0000000000000ull; 285 1.1 mrg // convert CA to DP 286 1.1 mrg da_h = CA.w[1]; 287 1.1 mrg da_l = CA.w[0]; 288 1.1 mrg da = da_h * t_scale.d + da_l; 289 1.1 mrg 290 1.1 mrg // quotient 291 1.1 mrg dq = da / db; 292 1.1 mrg Q2 = (UINT64) dq; 293 1.1 mrg 294 1.1 mrg // get w[0] remainder 295 1.1 mrg R = CA.w[0] - Q2 * B; 296 1.1 mrg 297 1.1 mrg // R<0 ? 298 1.1 mrg D = ((SINT64) R) >> 63; 299 1.1 mrg Q2 += D; 300 1.1 mrg R += (B & D); 301 1.1 mrg 302 1.1 mrg // now R<6*B 303 1.1 mrg 304 1.1 mrg // quick divide 305 1.1 mrg 306 1.1 mrg // 4*B 307 1.1 mrg B2 = B + B; 308 1.1 mrg B4 = B2 + B2; 309 1.1 mrg 310 1.1 mrg R = R - B4; 311 1.1 mrg // R<0 ? 312 1.1 mrg D = ((SINT64) R) >> 63; 313 1.1 mrg // restore R if negative 314 1.1 mrg R += (B4 & D); 315 1.1 mrg Q2 += ((~D) & 4); 316 1.1 mrg 317 1.1 mrg R = R - B2; 318 1.1 mrg // R<0 ? 319 1.1 mrg D = ((SINT64) R) >> 63; 320 1.1 mrg // restore R if negative 321 1.1 mrg R += (B2 & D); 322 1.1 mrg Q2 += ((~D) & 2); 323 1.1 mrg 324 1.1 mrg R = R - B; 325 1.1 mrg // R<0 ? 326 1.1 mrg D = ((SINT64) R) >> 63; 327 1.1 mrg // restore R if negative 328 1.1 mrg R += (B & D); 329 1.1 mrg Q2 += ((~D) & 1); 330 1.1 mrg 331 1.1 mrg Q += Q2; 332 1.1 mrg } 333 1.1 mrg 334 1.1 mrg #ifdef SET_STATUS_FLAGS 335 1.1 mrg if (R) { 336 1.1 mrg // set status flags 337 1.1 mrg __set_status_flags (pfpsf, INEXACT_EXCEPTION); 338 1.1 mrg } 339 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 340 1.1 mrg else 341 1.1 mrg #endif 342 1.1 mrg #else 343 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 344 1.1 mrg if (!R) 345 1.1 mrg #endif 346 1.1 mrg #endif 347 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 348 1.1 mrg { 349 1.1 mrg // eliminate trailing zeros 350 1.1 mrg 351 1.1 mrg // check whether CX, CY are short 352 1.1 mrg if ((coefficient_x <= 1024) && (coefficient_y <= 1024)) { 353 1.1 mrg i = (int) coefficient_y - 1; 354 1.1 mrg j = (int) coefficient_x - 1; 355 1.1 mrg // difference in powers of 2 factors for Y and X 356 1.1 mrg nzeros = ed2 - factors[i][0] + factors[j][0]; 357 1.1 mrg // difference in powers of 5 factors 358 1.1 mrg d5 = ed2 - factors[i][1] + factors[j][1]; 359 1.1 mrg if (d5 < nzeros) 360 1.1 mrg nzeros = d5; 361 1.1 mrg 362 1.1 mrg __mul_64x64_to_128 (CT, Q, reciprocals10_64[nzeros]); 363 1.1 mrg 364 1.1 mrg // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128 365 1.1 mrg amount = short_recip_scale[nzeros]; 366 1.1 mrg Q = CT.w[1] >> amount; 367 1.1 mrg 368 1.1 mrg diff_expon += nzeros; 369 1.1 mrg } else { 370 1.1 mrg tdigit[0] = Q & 0x3ffffff; 371 1.1 mrg tdigit[1] = 0; 372 1.1 mrg QX = Q >> 26; 373 1.1 mrg QX32 = QX; 374 1.1 mrg nzeros = 0; 375 1.1 mrg 376 1.1 mrg for (j = 0; QX32; j++, QX32 >>= 7) { 377 1.1 mrg k = (QX32 & 127); 378 1.1 mrg tdigit[0] += convert_table[j][k][0]; 379 1.1 mrg tdigit[1] += convert_table[j][k][1]; 380 1.1 mrg if (tdigit[0] >= 100000000) { 381 1.1 mrg tdigit[0] -= 100000000; 382 1.1 mrg tdigit[1]++; 383 1.1 mrg } 384 1.1 mrg } 385 1.1 mrg 386 1.1 mrg digit = tdigit[0]; 387 1.1 mrg if (!digit && !tdigit[1]) 388 1.1 mrg nzeros += 16; 389 1.1 mrg else { 390 1.1 mrg if (!digit) { 391 1.1 mrg nzeros += 8; 392 1.1 mrg digit = tdigit[1]; 393 1.1 mrg } 394 1.1 mrg // decompose digit 395 1.1 mrg PD = (UINT64) digit *0x068DB8BBull; 396 1.1 mrg digit_h = (UINT32) (PD >> 40); 397 1.1 mrg digit_low = digit - digit_h * 10000; 398 1.1 mrg 399 1.1 mrg if (!digit_low) 400 1.1 mrg nzeros += 4; 401 1.1 mrg else 402 1.1 mrg digit_h = digit_low; 403 1.1 mrg 404 1.1 mrg if (!(digit_h & 1)) 405 1.1 mrg nzeros += 406 1.1 mrg 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >> 407 1.1 mrg (digit_h & 7)); 408 1.1 mrg } 409 1.1 mrg 410 1.1 mrg if (nzeros) { 411 1.1 mrg __mul_64x64_to_128 (CT, Q, reciprocals10_64[nzeros]); 412 1.1 mrg 413 1.1 mrg // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128 414 1.1 mrg amount = short_recip_scale[nzeros]; 415 1.1 mrg Q = CT.w[1] >> amount; 416 1.1 mrg } 417 1.1 mrg diff_expon += nzeros; 418 1.1 mrg 419 1.1 mrg } 420 1.1 mrg if (diff_expon >= 0) { 421 1.1 mrg res = 422 1.1 mrg fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, Q, 423 1.1 mrg rnd_mode, pfpsf); 424 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 425 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 426 1.1 mrg #endif 427 1.1 mrg BID_RETURN (res); 428 1.1 mrg } 429 1.1 mrg } 430 1.1 mrg #endif 431 1.1 mrg 432 1.1 mrg if (diff_expon >= 0) { 433 1.1 mrg #ifdef IEEE_ROUND_NEAREST 434 1.1 mrg // round to nearest code 435 1.1 mrg // R*10 436 1.1 mrg R += R; 437 1.1 mrg R = (R << 2) + R; 438 1.1 mrg B5 = B4 + B; 439 1.1 mrg 440 1.1 mrg // compare 10*R to 5*B 441 1.1 mrg R = B5 - R; 442 1.1 mrg // correction for (R==0 && (Q&1)) 443 1.1 mrg R -= (Q & 1); 444 1.1 mrg // R<0 ? 445 1.1 mrg D = ((UINT64) R) >> 63; 446 1.1 mrg Q += D; 447 1.1 mrg #else 448 1.1 mrg #ifdef IEEE_ROUND_NEAREST_TIES_AWAY 449 1.1 mrg // round to nearest code 450 1.1 mrg // R*10 451 1.1 mrg R += R; 452 1.1 mrg R = (R << 2) + R; 453 1.1 mrg B5 = B4 + B; 454 1.1 mrg 455 1.1 mrg // compare 10*R to 5*B 456 1.1 mrg R = B5 - R; 457 1.1 mrg // correction for (R==0 && (Q&1)) 458 1.1 mrg R -= (Q & 1); 459 1.1 mrg // R<0 ? 460 1.1 mrg D = ((UINT64) R) >> 63; 461 1.1 mrg Q += D; 462 1.1 mrg #else 463 1.1 mrg rmode = rnd_mode; 464 1.1 mrg if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2) 465 1.1 mrg rmode = 3 - rmode; 466 1.1 mrg switch (rmode) { 467 1.1 mrg case 0: // round to nearest code 468 1.1 mrg case ROUNDING_TIES_AWAY: 469 1.1 mrg // R*10 470 1.1 mrg R += R; 471 1.1 mrg R = (R << 2) + R; 472 1.1 mrg B5 = B4 + B; 473 1.1 mrg // compare 10*R to 5*B 474 1.1 mrg R = B5 - R; 475 1.1 mrg // correction for (R==0 && (Q&1)) 476 1.1 mrg R -= ((Q | (rmode >> 2)) & 1); 477 1.1 mrg // R<0 ? 478 1.1 mrg D = ((UINT64) R) >> 63; 479 1.1 mrg Q += D; 480 1.1 mrg break; 481 1.1 mrg case ROUNDING_DOWN: 482 1.1 mrg case ROUNDING_TO_ZERO: 483 1.1 mrg break; 484 1.1 mrg default: // rounding up 485 1.1 mrg Q++; 486 1.1 mrg break; 487 1.1 mrg } 488 1.1 mrg #endif 489 1.1 mrg #endif 490 1.1 mrg 491 1.1 mrg res = 492 1.1 mrg fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, Q, rnd_mode, 493 1.1 mrg pfpsf); 494 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 495 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 496 1.1 mrg #endif 497 1.1 mrg BID_RETURN (res); 498 1.1 mrg } else { 499 1.1 mrg // UF occurs 500 1.1 mrg 501 1.1 mrg #ifdef SET_STATUS_FLAGS 502 1.1 mrg if ((diff_expon + 16 < 0)) { 503 1.1 mrg // set status flags 504 1.1 mrg __set_status_flags (pfpsf, INEXACT_EXCEPTION); 505 1.1 mrg } 506 1.1 mrg #endif 507 1.1 mrg rmode = rnd_mode; 508 1.1 mrg res = 509 1.1 mrg get_BID64_UF (sign_x ^ sign_y, diff_expon, Q, R, rmode, pfpsf); 510 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 511 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 512 1.1 mrg #endif 513 1.1 mrg BID_RETURN (res); 514 1.1 mrg 515 1.1 mrg } 516 1.1 mrg } 517 1.1 mrg 518 1.1 mrg 519 1.1 mrg 520 1.1 mrg TYPE0_FUNCTION_ARGTYPE1_ARG128 (UINT64, bid64dq_div, UINT64, x, y) 521 1.1 mrg UINT256 CA4 = 522 1.1 mrg { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256; 523 1.5 mrg UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp; 524 1.1 mrg UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, valid_y, PD, res; 525 1.1 mrg int_float fx, fy, f64; 526 1.1 mrg UINT32 QX32, tdigit[3], digit, digit_h, digit_low; 527 1.1 mrg int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2, 528 1.1 mrg digits_q, amount; 529 1.1 mrg int nzeros, i, j, k, d5, done = 0; 530 1.1 mrg unsigned rmode; 531 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 532 1.1 mrg fexcept_t binaryflags = 0; 533 1.1 mrg #endif 534 1.1 mrg 535 1.1 mrg valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y); 536 1.1 mrg 537 1.1 mrg // unpack arguments, check for NaN or Infinity 538 1.1 mrg CX.w[1] = 0; 539 1.1 mrg if (!unpack_BID64 (&sign_x, &exponent_x, &CX.w[0], (x))) { 540 1.1 mrg #ifdef SET_STATUS_FLAGS 541 1.1 mrg if (((y.w[1] & SNAN_MASK64) == SNAN_MASK64) || // y is sNaN 542 1.1 mrg ((x & SNAN_MASK64) == SNAN_MASK64)) 543 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 544 1.1 mrg #endif 545 1.1 mrg // test if x is NaN 546 1.1 mrg if (((x) & 0x7c00000000000000ull) == 0x7c00000000000000ull) { 547 1.1 mrg res = CX.w[0]; 548 1.1 mrg BID_RETURN (res & QUIET_MASK64); 549 1.1 mrg } 550 1.1 mrg // x is Infinity? 551 1.1 mrg if (((x) & 0x7800000000000000ull) == 0x7800000000000000ull) { 552 1.1 mrg // check if y is Inf. 553 1.1 mrg if (((y.w[1] & 0x7c00000000000000ull) == 0x7800000000000000ull)) 554 1.1 mrg // return NaN 555 1.1 mrg { 556 1.1 mrg #ifdef SET_STATUS_FLAGS 557 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 558 1.1 mrg #endif 559 1.1 mrg res = 0x7c00000000000000ull; 560 1.1 mrg BID_RETURN (res); 561 1.1 mrg } 562 1.1 mrg if (((y.w[1] & 0x7c00000000000000ull) != 0x7c00000000000000ull)) { 563 1.1 mrg // otherwise return +/-Inf 564 1.1 mrg res = 565 1.1 mrg (((x) ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull; 566 1.1 mrg BID_RETURN (res); 567 1.1 mrg } 568 1.1 mrg } 569 1.1 mrg // x is 0 570 1.1 mrg if ((y.w[1] & INFINITY_MASK64) != INFINITY_MASK64) { 571 1.1 mrg if ((!CY.w[0]) && !(CY.w[1] & 0x0001ffffffffffffull)) { 572 1.1 mrg #ifdef SET_STATUS_FLAGS 573 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 574 1.1 mrg #endif 575 1.1 mrg // x=y=0, return NaN 576 1.1 mrg res = 0x7c00000000000000ull; 577 1.1 mrg BID_RETURN (res); 578 1.1 mrg } 579 1.1 mrg // return 0 580 1.1 mrg res = ((x) ^ y.w[1]) & 0x8000000000000000ull; 581 1.1 mrg exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS_128; 582 1.1 mrg if (exponent_x > DECIMAL_MAX_EXPON_64) 583 1.1 mrg exponent_x = DECIMAL_MAX_EXPON_64; 584 1.1 mrg else if (exponent_x < 0) 585 1.1 mrg exponent_x = 0; 586 1.1 mrg res |= (((UINT64) exponent_x) << 53); 587 1.1 mrg BID_RETURN (res); 588 1.1 mrg } 589 1.1 mrg } 590 1.1 mrg exponent_x += (DECIMAL_EXPONENT_BIAS_128 - DECIMAL_EXPONENT_BIAS); 591 1.1 mrg if (!valid_y) { 592 1.1 mrg // y is Inf. or NaN 593 1.1 mrg 594 1.1 mrg // test if y is NaN 595 1.1 mrg if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) { 596 1.1 mrg #ifdef SET_STATUS_FLAGS 597 1.1 mrg if ((y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull) // sNaN 598 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 599 1.1 mrg #endif 600 1.1 mrg Tmp.w[1] = (CY.w[1] & 0x00003fffffffffffull); 601 1.1 mrg Tmp.w[0] = CY.w[0]; 602 1.1 mrg TP128 = reciprocals10_128[18]; 603 1.5 mrg __mul_128x128_high (Qh, Tmp, TP128); 604 1.1 mrg amount = recip_scale[18]; 605 1.1 mrg __shr_128 (Tmp, Qh, amount); 606 1.1 mrg res = (CY.w[1] & 0xfc00000000000000ull) | Tmp.w[0]; 607 1.1 mrg BID_RETURN (res); 608 1.1 mrg } 609 1.1 mrg // y is Infinity? 610 1.1 mrg if ((y.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) { 611 1.1 mrg // return +/-0 612 1.1 mrg res = sign_x ^ sign_y; 613 1.1 mrg BID_RETURN (res); 614 1.1 mrg } 615 1.1 mrg // y is 0, return +/-Inf 616 1.1 mrg res = 617 1.1 mrg (((x) ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull; 618 1.1 mrg #ifdef SET_STATUS_FLAGS 619 1.1 mrg __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION); 620 1.1 mrg #endif 621 1.1 mrg BID_RETURN (res); 622 1.1 mrg } 623 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 624 1.1 mrg (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS); 625 1.1 mrg #endif 626 1.1 mrg diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS; 627 1.1 mrg 628 1.1 mrg if (__unsigned_compare_gt_128 (CY, CX)) { 629 1.1 mrg // CX < CY 630 1.1 mrg 631 1.1 mrg // 2^64 632 1.1 mrg f64.i = 0x5f800000; 633 1.1 mrg 634 1.1 mrg // fx ~ CX, fy ~ CY 635 1.1 mrg fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0]; 636 1.1 mrg fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0]; 637 1.1 mrg // expon_cy - expon_cx 638 1.1 mrg bin_index = (fy.i - fx.i) >> 23; 639 1.1 mrg 640 1.1 mrg if (CX.w[1]) { 641 1.1 mrg T = power10_index_binexp_128[bin_index].w[0]; 642 1.1 mrg __mul_64x128_short (CA, T, CX); 643 1.1 mrg } else { 644 1.1 mrg T128 = power10_index_binexp_128[bin_index]; 645 1.1 mrg __mul_64x128_short (CA, CX.w[0], T128); 646 1.1 mrg } 647 1.1 mrg 648 1.1 mrg ed2 = 15; 649 1.1 mrg if (__unsigned_compare_gt_128 (CY, CA)) 650 1.1 mrg ed2++; 651 1.1 mrg 652 1.1 mrg T128 = power10_table_128[ed2]; 653 1.1 mrg __mul_128x128_to_256 (CA4, CA, T128); 654 1.1 mrg 655 1.1 mrg ed2 += estimate_decimal_digits[bin_index]; 656 1.1 mrg CQ.w[0] = CQ.w[1] = 0; 657 1.1 mrg diff_expon = diff_expon - ed2; 658 1.1 mrg 659 1.1 mrg } else { 660 1.1 mrg // get CQ = CX/CY 661 1.1 mrg __div_128_by_128 (&CQ, &CR, CX, CY); 662 1.1 mrg 663 1.1 mrg // get number of decimal digits in CQ 664 1.1 mrg // 2^64 665 1.1 mrg f64.i = 0x5f800000; 666 1.1 mrg fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0]; 667 1.1 mrg // binary expon. of CQ 668 1.1 mrg bin_expon = (fx.i - 0x3f800000) >> 23; 669 1.1 mrg 670 1.1 mrg digits_q = estimate_decimal_digits[bin_expon]; 671 1.1 mrg TP128.w[0] = power10_index_binexp_128[bin_expon].w[0]; 672 1.1 mrg TP128.w[1] = power10_index_binexp_128[bin_expon].w[1]; 673 1.1 mrg if (__unsigned_compare_ge_128 (CQ, TP128)) 674 1.1 mrg digits_q++; 675 1.1 mrg 676 1.1 mrg if (digits_q <= 16) { 677 1.1 mrg if (!CR.w[1] && !CR.w[0]) { 678 1.1 mrg res = get_BID64 (sign_x ^ sign_y, diff_expon, 679 1.1 mrg CQ.w[0], rnd_mode, pfpsf); 680 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 681 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 682 1.1 mrg #endif 683 1.1 mrg BID_RETURN (res); 684 1.1 mrg } 685 1.1 mrg 686 1.1 mrg ed2 = 16 - digits_q; 687 1.1 mrg T128.w[0] = power10_table_128[ed2].w[0]; 688 1.1 mrg __mul_64x128_to_192 (CA4, (T128.w[0]), CR); 689 1.1 mrg diff_expon = diff_expon - ed2; 690 1.1 mrg CQ.w[0] *= T128.w[0]; 691 1.1 mrg } else { 692 1.1 mrg ed2 = digits_q - 16; 693 1.1 mrg diff_expon += ed2; 694 1.1 mrg T128 = reciprocals10_128[ed2]; 695 1.1 mrg __mul_128x128_to_256 (P256, CQ, T128); 696 1.1 mrg amount = recip_scale[ed2]; 697 1.1 mrg CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount)); 698 1.1 mrg CQ.w[1] = 0; 699 1.1 mrg 700 1.1 mrg __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0])); 701 1.1 mrg 702 1.1 mrg __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]); 703 1.1 mrg QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0]; 704 1.1 mrg 705 1.1 mrg CA4.w[1] = CX.w[1] - QB256.w[1]; 706 1.1 mrg CA4.w[0] = CX.w[0] - QB256.w[0]; 707 1.1 mrg if (CX.w[0] < QB256.w[0]) 708 1.1 mrg CA4.w[1]--; 709 1.1 mrg if (CR.w[0] || CR.w[1]) 710 1.1 mrg CA4.w[0] |= 1; 711 1.1 mrg done = 1; 712 1.1 mrg 713 1.1 mrg } 714 1.1 mrg 715 1.1 mrg } 716 1.1 mrg if (!done) { 717 1.1 mrg __div_256_by_128 (&CQ, &CA4, CY); 718 1.1 mrg } 719 1.1 mrg 720 1.1 mrg 721 1.1 mrg 722 1.1 mrg #ifdef SET_STATUS_FLAGS 723 1.1 mrg if (CA4.w[0] || CA4.w[1]) { 724 1.1 mrg // set status flags 725 1.1 mrg __set_status_flags (pfpsf, INEXACT_EXCEPTION); 726 1.1 mrg } 727 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 728 1.1 mrg else 729 1.1 mrg #endif 730 1.1 mrg #else 731 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 732 1.1 mrg if (!CA4.w[0] && !CA4.w[1]) 733 1.1 mrg #endif 734 1.1 mrg #endif 735 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 736 1.1 mrg // check whether result is exact 737 1.1 mrg { 738 1.1 mrg // check whether CX, CY are short 739 1.1 mrg if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) { 740 1.1 mrg i = (int) CY.w[0] - 1; 741 1.1 mrg j = (int) CX.w[0] - 1; 742 1.1 mrg // difference in powers of 2 factors for Y and X 743 1.1 mrg nzeros = ed2 - factors[i][0] + factors[j][0]; 744 1.1 mrg // difference in powers of 5 factors 745 1.1 mrg d5 = ed2 - factors[i][1] + factors[j][1]; 746 1.1 mrg if (d5 < nzeros) 747 1.1 mrg nzeros = d5; 748 1.1 mrg // get P*(2^M[extra_digits])/10^extra_digits 749 1.5 mrg __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]); 750 1.1 mrg 751 1.1 mrg // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128 752 1.1 mrg amount = recip_scale[nzeros]; 753 1.1 mrg __shr_128_long (CQ, Qh, amount); 754 1.1 mrg 755 1.1 mrg diff_expon += nzeros; 756 1.1 mrg } else { 757 1.1 mrg // decompose Q as Qh*10^17 + Ql 758 1.1 mrg Q_low = CQ.w[0]; 759 1.1 mrg 760 1.1 mrg { 761 1.1 mrg tdigit[0] = Q_low & 0x3ffffff; 762 1.1 mrg tdigit[1] = 0; 763 1.1 mrg QX = Q_low >> 26; 764 1.1 mrg QX32 = QX; 765 1.1 mrg nzeros = 0; 766 1.1 mrg 767 1.1 mrg for (j = 0; QX32; j++, QX32 >>= 7) { 768 1.1 mrg k = (QX32 & 127); 769 1.1 mrg tdigit[0] += convert_table[j][k][0]; 770 1.1 mrg tdigit[1] += convert_table[j][k][1]; 771 1.1 mrg if (tdigit[0] >= 100000000) { 772 1.1 mrg tdigit[0] -= 100000000; 773 1.1 mrg tdigit[1]++; 774 1.1 mrg } 775 1.1 mrg } 776 1.1 mrg 777 1.1 mrg if (tdigit[1] >= 100000000) { 778 1.1 mrg tdigit[1] -= 100000000; 779 1.1 mrg if (tdigit[1] >= 100000000) 780 1.1 mrg tdigit[1] -= 100000000; 781 1.1 mrg } 782 1.1 mrg 783 1.1 mrg digit = tdigit[0]; 784 1.1 mrg if (!digit && !tdigit[1]) 785 1.1 mrg nzeros += 16; 786 1.1 mrg else { 787 1.1 mrg if (!digit) { 788 1.1 mrg nzeros += 8; 789 1.1 mrg digit = tdigit[1]; 790 1.1 mrg } 791 1.1 mrg // decompose digit 792 1.1 mrg PD = (UINT64) digit *0x068DB8BBull; 793 1.1 mrg digit_h = (UINT32) (PD >> 40); 794 1.1 mrg digit_low = digit - digit_h * 10000; 795 1.1 mrg 796 1.1 mrg if (!digit_low) 797 1.1 mrg nzeros += 4; 798 1.1 mrg else 799 1.1 mrg digit_h = digit_low; 800 1.1 mrg 801 1.1 mrg if (!(digit_h & 1)) 802 1.1 mrg nzeros += 803 1.1 mrg 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >> 804 1.1 mrg (digit_h & 7)); 805 1.1 mrg } 806 1.1 mrg 807 1.1 mrg if (nzeros) { 808 1.1 mrg // get P*(2^M[extra_digits])/10^extra_digits 809 1.5 mrg __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]); 810 1.1 mrg 811 1.1 mrg // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128 812 1.1 mrg amount = recip_scale[nzeros]; 813 1.1 mrg __shr_128 (CQ, Qh, amount); 814 1.1 mrg } 815 1.1 mrg diff_expon += nzeros; 816 1.1 mrg 817 1.1 mrg } 818 1.1 mrg } 819 1.1 mrg if(diff_expon>=0){ 820 1.1 mrg res = 821 1.1 mrg fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], 822 1.1 mrg rnd_mode, pfpsf); 823 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 824 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 825 1.1 mrg #endif 826 1.1 mrg BID_RETURN (res); 827 1.1 mrg } 828 1.1 mrg } 829 1.1 mrg #endif 830 1.1 mrg 831 1.1 mrg if (diff_expon >= 0) { 832 1.1 mrg #ifdef IEEE_ROUND_NEAREST 833 1.1 mrg // rounding 834 1.1 mrg // 2*CA4 - CY 835 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 836 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 837 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 838 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 839 1.1 mrg 840 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0; 841 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D); 842 1.1 mrg 843 1.1 mrg CQ.w[0] += carry64; 844 1.1 mrg #else 845 1.1 mrg #ifdef IEEE_ROUND_NEAREST_TIES_AWAY 846 1.1 mrg // rounding 847 1.1 mrg // 2*CA4 - CY 848 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 849 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 850 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 851 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 852 1.1 mrg 853 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1; 854 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D; 855 1.1 mrg 856 1.1 mrg CQ.w[0] += carry64; 857 1.1 mrg if (CQ.w[0] < carry64) 858 1.1 mrg CQ.w[1]++; 859 1.1 mrg #else 860 1.1 mrg rmode = rnd_mode; 861 1.1 mrg if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2) 862 1.1 mrg rmode = 3 - rmode; 863 1.1 mrg switch (rmode) { 864 1.1 mrg case ROUNDING_TO_NEAREST: // round to nearest code 865 1.1 mrg // rounding 866 1.1 mrg // 2*CA4 - CY 867 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 868 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 869 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 870 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 871 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0; 872 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D); 873 1.1 mrg CQ.w[0] += carry64; 874 1.1 mrg if (CQ.w[0] < carry64) 875 1.1 mrg CQ.w[1]++; 876 1.1 mrg break; 877 1.1 mrg case ROUNDING_TIES_AWAY: 878 1.1 mrg // rounding 879 1.1 mrg // 2*CA4 - CY 880 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 881 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 882 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 883 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 884 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1; 885 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D; 886 1.1 mrg CQ.w[0] += carry64; 887 1.1 mrg if (CQ.w[0] < carry64) 888 1.1 mrg CQ.w[1]++; 889 1.1 mrg break; 890 1.1 mrg case ROUNDING_DOWN: 891 1.1 mrg case ROUNDING_TO_ZERO: 892 1.1 mrg break; 893 1.1 mrg default: // rounding up 894 1.1 mrg CQ.w[0]++; 895 1.1 mrg if (!CQ.w[0]) 896 1.1 mrg CQ.w[1]++; 897 1.1 mrg break; 898 1.1 mrg } 899 1.1 mrg #endif 900 1.1 mrg #endif 901 1.1 mrg 902 1.1 mrg res = 903 1.1 mrg fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode, 904 1.1 mrg pfpsf); 905 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 906 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 907 1.1 mrg #endif 908 1.1 mrg BID_RETURN (res); 909 1.1 mrg } else { 910 1.1 mrg // UF occurs 911 1.1 mrg 912 1.1 mrg #ifdef SET_STATUS_FLAGS 913 1.1 mrg if ((diff_expon + 16 < 0)) { 914 1.1 mrg // set status flags 915 1.1 mrg __set_status_flags (pfpsf, INEXACT_EXCEPTION); 916 1.1 mrg } 917 1.1 mrg #endif 918 1.1 mrg rmode = rnd_mode; 919 1.1 mrg res = 920 1.1 mrg get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf); 921 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 922 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 923 1.1 mrg #endif 924 1.1 mrg BID_RETURN (res); 925 1.1 mrg 926 1.1 mrg } 927 1.1 mrg 928 1.1 mrg } 929 1.1 mrg 930 1.1 mrg 931 1.1 mrg //#define LEAVE_TRAILING_ZEROS 932 1.1 mrg 933 1.1 mrg TYPE0_FUNCTION_ARG128_ARGTYPE2 (UINT64, bid64qd_div, x, UINT64, y) 934 1.1 mrg 935 1.1 mrg UINT256 CA4 = 936 1.1 mrg { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256; 937 1.5 mrg UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp; 938 1.1 mrg UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, PD, res, valid_y; 939 1.1 mrg int_float fx, fy, f64; 940 1.1 mrg UINT32 QX32, tdigit[3], digit, digit_h, digit_low; 941 1.1 mrg int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2, 942 1.1 mrg digits_q, amount; 943 1.1 mrg int nzeros, i, j, k, d5, done = 0; 944 1.1 mrg unsigned rmode; 945 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 946 1.1 mrg fexcept_t binaryflags = 0; 947 1.1 mrg #endif 948 1.1 mrg 949 1.1 mrg valid_y = unpack_BID64 (&sign_y, &exponent_y, &CY.w[0], (y)); 950 1.1 mrg 951 1.1 mrg // unpack arguments, check for NaN or Infinity 952 1.1 mrg if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) { 953 1.1 mrg // test if x is NaN 954 1.1 mrg if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) { 955 1.1 mrg #ifdef SET_STATUS_FLAGS 956 1.1 mrg if ((x.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull || // sNaN 957 1.1 mrg (y & 0x7e00000000000000ull) == 0x7e00000000000000ull) 958 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 959 1.1 mrg #endif 960 1.1 mrg Tmp.w[1] = (CX.w[1] & 0x00003fffffffffffull); 961 1.1 mrg Tmp.w[0] = CX.w[0]; 962 1.1 mrg TP128 = reciprocals10_128[18]; 963 1.5 mrg __mul_128x128_high (Qh, Tmp, TP128); 964 1.1 mrg amount = recip_scale[18]; 965 1.1 mrg __shr_128 (Tmp, Qh, amount); 966 1.1 mrg res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0]; 967 1.1 mrg BID_RETURN (res); 968 1.1 mrg } 969 1.1 mrg // x is Infinity? 970 1.1 mrg if ((x.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) { 971 1.1 mrg // check if y is Inf. 972 1.1 mrg if (((y & 0x7c00000000000000ull) == 0x7800000000000000ull)) 973 1.1 mrg // return NaN 974 1.1 mrg { 975 1.1 mrg #ifdef SET_STATUS_FLAGS 976 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 977 1.1 mrg #endif 978 1.1 mrg res = 0x7c00000000000000ull; 979 1.1 mrg BID_RETURN (res); 980 1.1 mrg } 981 1.1 mrg if (((y & 0x7c00000000000000ull) != 0x7c00000000000000ull)) { 982 1.1 mrg // otherwise return +/-Inf 983 1.1 mrg res = 984 1.1 mrg ((x.w[1] ^ (y)) & 0x8000000000000000ull) | 0x7800000000000000ull; 985 1.1 mrg BID_RETURN (res); 986 1.1 mrg } 987 1.1 mrg } 988 1.1 mrg // x is 0 989 1.1 mrg if (((y & INFINITY_MASK64) != INFINITY_MASK64) && 990 1.1 mrg !(CY.w[0])) { 991 1.1 mrg #ifdef SET_STATUS_FLAGS 992 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 993 1.1 mrg #endif 994 1.1 mrg // x=y=0, return NaN 995 1.1 mrg res = 0x7c00000000000000ull; 996 1.1 mrg BID_RETURN (res); 997 1.1 mrg } 998 1.1 mrg // return 0 999 1.1 mrg if (((y & 0x7800000000000000ull) != 0x7800000000000000ull)) { 1000 1.1 mrg if (!CY.w[0]) { 1001 1.1 mrg #ifdef SET_STATUS_FLAGS 1002 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 1003 1.1 mrg #endif 1004 1.1 mrg res = 0x7c00000000000000ull; 1005 1.1 mrg BID_RETURN (res); 1006 1.1 mrg } 1007 1.1 mrg exponent_x = 1008 1.1 mrg exponent_x - exponent_y - DECIMAL_EXPONENT_BIAS_128 + 1009 1.1 mrg (DECIMAL_EXPONENT_BIAS << 1); 1010 1.1 mrg if (exponent_x > DECIMAL_MAX_EXPON_64) 1011 1.1 mrg exponent_x = DECIMAL_MAX_EXPON_64; 1012 1.1 mrg else if (exponent_x < 0) 1013 1.1 mrg exponent_x = 0; 1014 1.1 mrg res = (sign_x ^ sign_y) | (((UINT64) exponent_x) << 53); 1015 1.1 mrg BID_RETURN (res); 1016 1.1 mrg } 1017 1.1 mrg } 1018 1.1 mrg CY.w[1] = 0; 1019 1.1 mrg if (!valid_y) { 1020 1.1 mrg // y is Inf. or NaN 1021 1.1 mrg 1022 1.1 mrg // test if y is NaN 1023 1.1 mrg if ((y & NAN_MASK64) == NAN_MASK64) { 1024 1.1 mrg #ifdef SET_STATUS_FLAGS 1025 1.1 mrg if ((y & SNAN_MASK64) == SNAN_MASK64) // sNaN 1026 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 1027 1.1 mrg #endif 1028 1.1 mrg BID_RETURN (CY.w[0] & QUIET_MASK64); 1029 1.1 mrg } 1030 1.1 mrg // y is Infinity? 1031 1.1 mrg if (((y) & 0x7800000000000000ull) == 0x7800000000000000ull) { 1032 1.1 mrg // return +/-0 1033 1.1 mrg res = sign_x ^ sign_y; 1034 1.1 mrg BID_RETURN (res); 1035 1.1 mrg } 1036 1.1 mrg // y is 0, return +/-Inf 1037 1.1 mrg res = 1038 1.1 mrg ((x.w[1] ^ (y)) & 0x8000000000000000ull) | 0x7800000000000000ull; 1039 1.1 mrg #ifdef SET_STATUS_FLAGS 1040 1.1 mrg __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION); 1041 1.1 mrg #endif 1042 1.1 mrg BID_RETURN (res); 1043 1.1 mrg } 1044 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 1045 1.1 mrg (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS); 1046 1.1 mrg #endif 1047 1.1 mrg diff_expon = 1048 1.1 mrg exponent_x - exponent_y - DECIMAL_EXPONENT_BIAS_128 + 1049 1.1 mrg (DECIMAL_EXPONENT_BIAS << 1); 1050 1.1 mrg 1051 1.1 mrg if (__unsigned_compare_gt_128 (CY, CX)) { 1052 1.1 mrg // CX < CY 1053 1.1 mrg 1054 1.1 mrg // 2^64 1055 1.1 mrg f64.i = 0x5f800000; 1056 1.1 mrg 1057 1.1 mrg // fx ~ CX, fy ~ CY 1058 1.1 mrg fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0]; 1059 1.1 mrg fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0]; 1060 1.1 mrg // expon_cy - expon_cx 1061 1.1 mrg bin_index = (fy.i - fx.i) >> 23; 1062 1.1 mrg 1063 1.1 mrg if (CX.w[1]) { 1064 1.1 mrg T = power10_index_binexp_128[bin_index].w[0]; 1065 1.1 mrg __mul_64x128_short (CA, T, CX); 1066 1.1 mrg } else { 1067 1.1 mrg T128 = power10_index_binexp_128[bin_index]; 1068 1.1 mrg __mul_64x128_short (CA, CX.w[0], T128); 1069 1.1 mrg } 1070 1.1 mrg 1071 1.1 mrg ed2 = 15; 1072 1.1 mrg if (__unsigned_compare_gt_128 (CY, CA)) 1073 1.1 mrg ed2++; 1074 1.1 mrg 1075 1.1 mrg T128 = power10_table_128[ed2]; 1076 1.1 mrg __mul_128x128_to_256 (CA4, CA, T128); 1077 1.1 mrg 1078 1.1 mrg ed2 += estimate_decimal_digits[bin_index]; 1079 1.1 mrg CQ.w[0] = CQ.w[1] = 0; 1080 1.1 mrg diff_expon = diff_expon - ed2; 1081 1.1 mrg 1082 1.1 mrg } else { 1083 1.1 mrg // get CQ = CX/CY 1084 1.1 mrg __div_128_by_128 (&CQ, &CR, CX, CY); 1085 1.1 mrg 1086 1.1 mrg // get number of decimal digits in CQ 1087 1.1 mrg // 2^64 1088 1.1 mrg f64.i = 0x5f800000; 1089 1.1 mrg fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0]; 1090 1.1 mrg // binary expon. of CQ 1091 1.1 mrg bin_expon = (fx.i - 0x3f800000) >> 23; 1092 1.1 mrg 1093 1.1 mrg digits_q = estimate_decimal_digits[bin_expon]; 1094 1.1 mrg TP128.w[0] = power10_index_binexp_128[bin_expon].w[0]; 1095 1.1 mrg TP128.w[1] = power10_index_binexp_128[bin_expon].w[1]; 1096 1.1 mrg if (__unsigned_compare_ge_128 (CQ, TP128)) 1097 1.1 mrg digits_q++; 1098 1.1 mrg 1099 1.1 mrg if (digits_q <= 16) { 1100 1.1 mrg if (!CR.w[1] && !CR.w[0]) { 1101 1.1 mrg res = get_BID64 (sign_x ^ sign_y, diff_expon, 1102 1.1 mrg CQ.w[0], rnd_mode, pfpsf); 1103 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 1104 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 1105 1.1 mrg #endif 1106 1.1 mrg BID_RETURN (res); 1107 1.1 mrg } 1108 1.1 mrg 1109 1.1 mrg ed2 = 16 - digits_q; 1110 1.1 mrg T128.w[0] = power10_table_128[ed2].w[0]; 1111 1.1 mrg __mul_64x128_to_192 (CA4, (T128.w[0]), CR); 1112 1.1 mrg diff_expon = diff_expon - ed2; 1113 1.1 mrg CQ.w[0] *= T128.w[0]; 1114 1.1 mrg } else { 1115 1.1 mrg ed2 = digits_q - 16; 1116 1.1 mrg diff_expon += ed2; 1117 1.1 mrg T128 = reciprocals10_128[ed2]; 1118 1.1 mrg __mul_128x128_to_256 (P256, CQ, T128); 1119 1.1 mrg amount = recip_scale[ed2]; 1120 1.1 mrg CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount)); 1121 1.1 mrg CQ.w[1] = 0; 1122 1.1 mrg 1123 1.1 mrg __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0])); 1124 1.1 mrg 1125 1.1 mrg __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]); 1126 1.1 mrg QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0]; 1127 1.1 mrg 1128 1.1 mrg CA4.w[1] = CX.w[1] - QB256.w[1]; 1129 1.1 mrg CA4.w[0] = CX.w[0] - QB256.w[0]; 1130 1.1 mrg if (CX.w[0] < QB256.w[0]) 1131 1.1 mrg CA4.w[1]--; 1132 1.1 mrg if (CR.w[0] || CR.w[1]) 1133 1.1 mrg CA4.w[0] |= 1; 1134 1.1 mrg done = 1; 1135 1.1 mrg if(CA4.w[1]|CA4.w[0]) { 1136 1.1 mrg __mul_64x128_low(CY, (power10_table_128[ed2].w[0]),CY); 1137 1.1 mrg } 1138 1.1 mrg 1139 1.1 mrg } 1140 1.1 mrg 1141 1.1 mrg } 1142 1.1 mrg 1143 1.1 mrg if (!done) { 1144 1.1 mrg __div_256_by_128 (&CQ, &CA4, CY); 1145 1.1 mrg } 1146 1.1 mrg 1147 1.1 mrg #ifdef SET_STATUS_FLAGS 1148 1.1 mrg if (CA4.w[0] || CA4.w[1]) { 1149 1.1 mrg // set status flags 1150 1.1 mrg __set_status_flags (pfpsf, INEXACT_EXCEPTION); 1151 1.1 mrg } 1152 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 1153 1.1 mrg else 1154 1.1 mrg #endif 1155 1.1 mrg #else 1156 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 1157 1.1 mrg if (!CA4.w[0] && !CA4.w[1]) 1158 1.1 mrg #endif 1159 1.1 mrg #endif 1160 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 1161 1.1 mrg // check whether result is exact 1162 1.1 mrg { 1163 1.1 mrg if(!done) { 1164 1.1 mrg // check whether CX, CY are short 1165 1.1 mrg if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) { 1166 1.1 mrg i = (int) CY.w[0] - 1; 1167 1.1 mrg j = (int) CX.w[0] - 1; 1168 1.1 mrg // difference in powers of 2 factors for Y and X 1169 1.1 mrg nzeros = ed2 - factors[i][0] + factors[j][0]; 1170 1.1 mrg // difference in powers of 5 factors 1171 1.1 mrg d5 = ed2 - factors[i][1] + factors[j][1]; 1172 1.1 mrg if (d5 < nzeros) 1173 1.1 mrg nzeros = d5; 1174 1.1 mrg // get P*(2^M[extra_digits])/10^extra_digits 1175 1.5 mrg __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]); 1176 1.1 mrg //__mul_128x128_to_256(P256, CQ, reciprocals10_128[nzeros]);Qh.w[1]=P256.w[3];Qh.w[0]=P256.w[2]; 1177 1.1 mrg 1178 1.1 mrg // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128 1179 1.1 mrg amount = recip_scale[nzeros]; 1180 1.1 mrg __shr_128_long (CQ, Qh, amount); 1181 1.1 mrg 1182 1.1 mrg diff_expon += nzeros; 1183 1.1 mrg } else { 1184 1.1 mrg // decompose Q as Qh*10^17 + Ql 1185 1.1 mrg //T128 = reciprocals10_128[17]; 1186 1.1 mrg Q_low = CQ.w[0]; 1187 1.1 mrg 1188 1.1 mrg { 1189 1.1 mrg tdigit[0] = Q_low & 0x3ffffff; 1190 1.1 mrg tdigit[1] = 0; 1191 1.1 mrg QX = Q_low >> 26; 1192 1.1 mrg QX32 = QX; 1193 1.1 mrg nzeros = 0; 1194 1.1 mrg 1195 1.1 mrg for (j = 0; QX32; j++, QX32 >>= 7) { 1196 1.1 mrg k = (QX32 & 127); 1197 1.1 mrg tdigit[0] += convert_table[j][k][0]; 1198 1.1 mrg tdigit[1] += convert_table[j][k][1]; 1199 1.1 mrg if (tdigit[0] >= 100000000) { 1200 1.1 mrg tdigit[0] -= 100000000; 1201 1.1 mrg tdigit[1]++; 1202 1.1 mrg } 1203 1.1 mrg } 1204 1.1 mrg 1205 1.1 mrg if (tdigit[1] >= 100000000) { 1206 1.1 mrg tdigit[1] -= 100000000; 1207 1.1 mrg if (tdigit[1] >= 100000000) 1208 1.1 mrg tdigit[1] -= 100000000; 1209 1.1 mrg } 1210 1.1 mrg 1211 1.1 mrg digit = tdigit[0]; 1212 1.1 mrg if (!digit && !tdigit[1]) 1213 1.1 mrg nzeros += 16; 1214 1.1 mrg else { 1215 1.1 mrg if (!digit) { 1216 1.1 mrg nzeros += 8; 1217 1.1 mrg digit = tdigit[1]; 1218 1.1 mrg } 1219 1.1 mrg // decompose digit 1220 1.1 mrg PD = (UINT64) digit *0x068DB8BBull; 1221 1.1 mrg digit_h = (UINT32) (PD >> 40); 1222 1.1 mrg digit_low = digit - digit_h * 10000; 1223 1.1 mrg 1224 1.1 mrg if (!digit_low) 1225 1.1 mrg nzeros += 4; 1226 1.1 mrg else 1227 1.1 mrg digit_h = digit_low; 1228 1.1 mrg 1229 1.1 mrg if (!(digit_h & 1)) 1230 1.1 mrg nzeros += 1231 1.1 mrg 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >> 1232 1.1 mrg (digit_h & 7)); 1233 1.1 mrg } 1234 1.1 mrg 1235 1.1 mrg if (nzeros) { 1236 1.1 mrg // get P*(2^M[extra_digits])/10^extra_digits 1237 1.5 mrg __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]); 1238 1.1 mrg 1239 1.1 mrg // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128 1240 1.1 mrg amount = recip_scale[nzeros]; 1241 1.1 mrg __shr_128 (CQ, Qh, amount); 1242 1.1 mrg } 1243 1.1 mrg diff_expon += nzeros; 1244 1.1 mrg 1245 1.1 mrg } 1246 1.1 mrg } 1247 1.1 mrg } 1248 1.1 mrg if(diff_expon>=0){ 1249 1.1 mrg res = 1250 1.1 mrg fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], 1251 1.1 mrg rnd_mode, pfpsf); 1252 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 1253 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 1254 1.1 mrg #endif 1255 1.1 mrg BID_RETURN (res); 1256 1.1 mrg } 1257 1.1 mrg } 1258 1.1 mrg #endif 1259 1.1 mrg 1260 1.1 mrg if (diff_expon >= 0) { 1261 1.1 mrg #ifdef IEEE_ROUND_NEAREST 1262 1.1 mrg // rounding 1263 1.1 mrg // 2*CA4 - CY 1264 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 1265 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 1266 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 1267 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 1268 1.1 mrg 1269 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0; 1270 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D); 1271 1.1 mrg 1272 1.1 mrg CQ.w[0] += carry64; 1273 1.1 mrg //if(CQ.w[0]<carry64) 1274 1.1 mrg //CQ.w[1] ++; 1275 1.1 mrg #else 1276 1.1 mrg #ifdef IEEE_ROUND_NEAREST_TIES_AWAY 1277 1.1 mrg // rounding 1278 1.1 mrg // 2*CA4 - CY 1279 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 1280 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 1281 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 1282 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 1283 1.1 mrg 1284 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1; 1285 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D; 1286 1.1 mrg 1287 1.1 mrg CQ.w[0] += carry64; 1288 1.1 mrg if (CQ.w[0] < carry64) 1289 1.1 mrg CQ.w[1]++; 1290 1.1 mrg #else 1291 1.1 mrg rmode = rnd_mode; 1292 1.1 mrg if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2) 1293 1.1 mrg rmode = 3 - rmode; 1294 1.1 mrg switch (rmode) { 1295 1.1 mrg case ROUNDING_TO_NEAREST: // round to nearest code 1296 1.1 mrg // rounding 1297 1.1 mrg // 2*CA4 - CY 1298 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 1299 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 1300 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 1301 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 1302 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0; 1303 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D); 1304 1.1 mrg CQ.w[0] += carry64; 1305 1.1 mrg if (CQ.w[0] < carry64) 1306 1.1 mrg CQ.w[1]++; 1307 1.1 mrg break; 1308 1.1 mrg case ROUNDING_TIES_AWAY: 1309 1.1 mrg // rounding 1310 1.1 mrg // 2*CA4 - CY 1311 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 1312 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 1313 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 1314 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 1315 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1; 1316 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D; 1317 1.1 mrg CQ.w[0] += carry64; 1318 1.1 mrg if (CQ.w[0] < carry64) 1319 1.1 mrg CQ.w[1]++; 1320 1.1 mrg break; 1321 1.1 mrg case ROUNDING_DOWN: 1322 1.1 mrg case ROUNDING_TO_ZERO: 1323 1.1 mrg break; 1324 1.1 mrg default: // rounding up 1325 1.1 mrg CQ.w[0]++; 1326 1.1 mrg if (!CQ.w[0]) 1327 1.1 mrg CQ.w[1]++; 1328 1.1 mrg break; 1329 1.1 mrg } 1330 1.1 mrg #endif 1331 1.1 mrg #endif 1332 1.1 mrg 1333 1.1 mrg 1334 1.1 mrg res = 1335 1.1 mrg fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode, 1336 1.1 mrg pfpsf); 1337 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 1338 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 1339 1.1 mrg #endif 1340 1.1 mrg BID_RETURN (res); 1341 1.1 mrg } else { 1342 1.1 mrg // UF occurs 1343 1.1 mrg 1344 1.1 mrg #ifdef SET_STATUS_FLAGS 1345 1.1 mrg if ((diff_expon + 16 < 0)) { 1346 1.1 mrg // set status flags 1347 1.1 mrg __set_status_flags (pfpsf, INEXACT_EXCEPTION); 1348 1.1 mrg } 1349 1.1 mrg #endif 1350 1.1 mrg rmode = rnd_mode; 1351 1.1 mrg res = 1352 1.1 mrg get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf); 1353 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 1354 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 1355 1.1 mrg #endif 1356 1.1 mrg BID_RETURN (res); 1357 1.1 mrg 1358 1.1 mrg } 1359 1.1 mrg 1360 1.1 mrg } 1361 1.1 mrg 1362 1.1 mrg //#define LEAVE_TRAILING_ZEROS 1363 1.1 mrg 1364 1.1 mrg extern UINT32 convert_table[5][128][2]; 1365 1.1 mrg extern SINT8 factors[][2]; 1366 1.1 mrg extern UINT8 packed_10000_zeros[]; 1367 1.1 mrg 1368 1.1 mrg 1369 1.1 mrg //UINT64* bid64_div128x128(UINT64 res, UINT128 *px, UINT128 *py, unsigned rnd_mode, unsigned *pfpsf) 1370 1.1 mrg 1371 1.1 mrg TYPE0_FUNCTION_ARG128_ARG128 (UINT64, bid64qq_div, x, y) 1372 1.1 mrg UINT256 CA4 = 1373 1.1 mrg { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256; 1374 1.5 mrg UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp; 1375 1.1 mrg UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, valid_y, PD, res; 1376 1.1 mrg int_float fx, fy, f64; 1377 1.1 mrg UINT32 QX32, tdigit[3], digit, digit_h, digit_low; 1378 1.1 mrg int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2, 1379 1.1 mrg digits_q, amount; 1380 1.1 mrg int nzeros, i, j, k, d5, done = 0; 1381 1.1 mrg unsigned rmode; 1382 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 1383 1.1 mrg fexcept_t binaryflags = 0; 1384 1.1 mrg #endif 1385 1.1 mrg 1386 1.1 mrg valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y); 1387 1.1 mrg 1388 1.1 mrg // unpack arguments, check for NaN or Infinity 1389 1.1 mrg if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) { 1390 1.1 mrg // test if x is NaN 1391 1.1 mrg if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) { 1392 1.1 mrg #ifdef SET_STATUS_FLAGS 1393 1.1 mrg if ((x.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull || // sNaN 1394 1.1 mrg (y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull) 1395 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 1396 1.1 mrg #endif 1397 1.1 mrg Tmp.w[1] = (CX.w[1] & 0x00003fffffffffffull); 1398 1.1 mrg Tmp.w[0] = CX.w[0]; 1399 1.1 mrg TP128 = reciprocals10_128[18]; 1400 1.5 mrg __mul_128x128_high (Qh, Tmp, TP128); 1401 1.1 mrg amount = recip_scale[18]; 1402 1.1 mrg __shr_128 (Tmp, Qh, amount); 1403 1.1 mrg res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0]; 1404 1.1 mrg BID_RETURN (res); 1405 1.1 mrg } 1406 1.1 mrg // x is Infinity? 1407 1.1 mrg if ((x.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) { 1408 1.1 mrg // check if y is Inf. 1409 1.1 mrg if (((y.w[1] & 0x7c00000000000000ull) == 0x7800000000000000ull)) 1410 1.1 mrg // return NaN 1411 1.1 mrg { 1412 1.1 mrg #ifdef SET_STATUS_FLAGS 1413 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 1414 1.1 mrg #endif 1415 1.1 mrg res = 0x7c00000000000000ull; 1416 1.1 mrg BID_RETURN (res); 1417 1.1 mrg } 1418 1.1 mrg if (((y.w[1] & 0x7c00000000000000ull) != 0x7c00000000000000ull)) { 1419 1.1 mrg // otherwise return +/-Inf 1420 1.1 mrg res = 1421 1.1 mrg ((x.w[1] ^ y. 1422 1.1 mrg w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull; 1423 1.1 mrg BID_RETURN (res); 1424 1.1 mrg } 1425 1.1 mrg } 1426 1.1 mrg // x is 0 1427 1.1 mrg if (((y.w[1] & 0x7800000000000000ull) != 0x7800000000000000ull)) { 1428 1.1 mrg if ((!CY.w[0]) && !(CY.w[1] & 0x0001ffffffffffffull)) { 1429 1.1 mrg #ifdef SET_STATUS_FLAGS 1430 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 1431 1.1 mrg #endif 1432 1.1 mrg // x=y=0, return NaN 1433 1.1 mrg res = 0x7c00000000000000ull; 1434 1.1 mrg BID_RETURN (res); 1435 1.1 mrg } 1436 1.1 mrg // return 0 1437 1.1 mrg res = (x.w[1] ^ y.w[1]) & 0x8000000000000000ull; 1438 1.1 mrg exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS; 1439 1.1 mrg if (exponent_x > DECIMAL_MAX_EXPON_64) 1440 1.1 mrg exponent_x = DECIMAL_MAX_EXPON_64; 1441 1.1 mrg else if (exponent_x < 0) 1442 1.1 mrg exponent_x = 0; 1443 1.1 mrg res |= (((UINT64) exponent_x) << 53); 1444 1.1 mrg BID_RETURN (res); 1445 1.1 mrg } 1446 1.1 mrg } 1447 1.1 mrg if (!valid_y) { 1448 1.1 mrg // y is Inf. or NaN 1449 1.1 mrg 1450 1.1 mrg // test if y is NaN 1451 1.1 mrg if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) { 1452 1.1 mrg #ifdef SET_STATUS_FLAGS 1453 1.1 mrg if ((y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull) // sNaN 1454 1.1 mrg __set_status_flags (pfpsf, INVALID_EXCEPTION); 1455 1.1 mrg #endif 1456 1.1 mrg Tmp.w[1] = (CY.w[1] & 0x00003fffffffffffull); 1457 1.1 mrg Tmp.w[0] = CY.w[0]; 1458 1.1 mrg TP128 = reciprocals10_128[18]; 1459 1.5 mrg __mul_128x128_high (Qh, Tmp, TP128); 1460 1.1 mrg amount = recip_scale[18]; 1461 1.1 mrg __shr_128 (Tmp, Qh, amount); 1462 1.1 mrg res = (CY.w[1] & 0xfc00000000000000ull) | Tmp.w[0]; 1463 1.1 mrg BID_RETURN (res); 1464 1.1 mrg } 1465 1.1 mrg // y is Infinity? 1466 1.1 mrg if ((y.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) { 1467 1.1 mrg // return +/-0 1468 1.1 mrg res = sign_x ^ sign_y; 1469 1.1 mrg BID_RETURN (res); 1470 1.1 mrg } 1471 1.1 mrg // y is 0, return +/-Inf 1472 1.1 mrg res = 1473 1.1 mrg ((x.w[1] ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull; 1474 1.1 mrg #ifdef SET_STATUS_FLAGS 1475 1.1 mrg __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION); 1476 1.1 mrg #endif 1477 1.1 mrg BID_RETURN (res); 1478 1.1 mrg } 1479 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 1480 1.1 mrg (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS); 1481 1.1 mrg #endif 1482 1.1 mrg diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS; 1483 1.1 mrg 1484 1.1 mrg if (__unsigned_compare_gt_128 (CY, CX)) { 1485 1.1 mrg // CX < CY 1486 1.1 mrg 1487 1.1 mrg // 2^64 1488 1.1 mrg f64.i = 0x5f800000; 1489 1.1 mrg 1490 1.1 mrg // fx ~ CX, fy ~ CY 1491 1.1 mrg fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0]; 1492 1.1 mrg fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0]; 1493 1.1 mrg // expon_cy - expon_cx 1494 1.1 mrg bin_index = (fy.i - fx.i) >> 23; 1495 1.1 mrg 1496 1.1 mrg if (CX.w[1]) { 1497 1.1 mrg T = power10_index_binexp_128[bin_index].w[0]; 1498 1.1 mrg __mul_64x128_short (CA, T, CX); 1499 1.1 mrg } else { 1500 1.1 mrg T128 = power10_index_binexp_128[bin_index]; 1501 1.1 mrg __mul_64x128_short (CA, CX.w[0], T128); 1502 1.1 mrg } 1503 1.1 mrg 1504 1.1 mrg ed2 = 15; 1505 1.1 mrg if (__unsigned_compare_gt_128 (CY, CA)) 1506 1.1 mrg ed2++; 1507 1.1 mrg 1508 1.1 mrg T128 = power10_table_128[ed2]; 1509 1.1 mrg __mul_128x128_to_256 (CA4, CA, T128); 1510 1.1 mrg 1511 1.1 mrg ed2 += estimate_decimal_digits[bin_index]; 1512 1.1 mrg CQ.w[0] = CQ.w[1] = 0; 1513 1.1 mrg diff_expon = diff_expon - ed2; 1514 1.1 mrg 1515 1.1 mrg } else { 1516 1.1 mrg // get CQ = CX/CY 1517 1.1 mrg __div_128_by_128 (&CQ, &CR, CX, CY); 1518 1.1 mrg 1519 1.1 mrg // get number of decimal digits in CQ 1520 1.1 mrg // 2^64 1521 1.1 mrg f64.i = 0x5f800000; 1522 1.1 mrg fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0]; 1523 1.1 mrg // binary expon. of CQ 1524 1.1 mrg bin_expon = (fx.i - 0x3f800000) >> 23; 1525 1.1 mrg 1526 1.1 mrg digits_q = estimate_decimal_digits[bin_expon]; 1527 1.1 mrg TP128.w[0] = power10_index_binexp_128[bin_expon].w[0]; 1528 1.1 mrg TP128.w[1] = power10_index_binexp_128[bin_expon].w[1]; 1529 1.1 mrg if (__unsigned_compare_ge_128 (CQ, TP128)) 1530 1.1 mrg digits_q++; 1531 1.1 mrg 1532 1.1 mrg if (digits_q <= 16) { 1533 1.1 mrg if (!CR.w[1] && !CR.w[0]) { 1534 1.1 mrg res = get_BID64 (sign_x ^ sign_y, diff_expon, 1535 1.1 mrg CQ.w[0], rnd_mode, pfpsf); 1536 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 1537 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 1538 1.1 mrg #endif 1539 1.1 mrg BID_RETURN (res); 1540 1.1 mrg } 1541 1.1 mrg 1542 1.1 mrg ed2 = 16 - digits_q; 1543 1.1 mrg T128.w[0] = power10_table_128[ed2].w[0]; 1544 1.1 mrg __mul_64x128_to_192 (CA4, (T128.w[0]), CR); 1545 1.1 mrg diff_expon = diff_expon - ed2; 1546 1.1 mrg CQ.w[0] *= T128.w[0]; 1547 1.1 mrg } else { 1548 1.1 mrg ed2 = digits_q - 16; 1549 1.1 mrg diff_expon += ed2; 1550 1.1 mrg T128 = reciprocals10_128[ed2]; 1551 1.1 mrg __mul_128x128_to_256 (P256, CQ, T128); 1552 1.1 mrg amount = recip_scale[ed2]; 1553 1.1 mrg CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount)); 1554 1.1 mrg CQ.w[1] = 0; 1555 1.1 mrg 1556 1.1 mrg __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0])); 1557 1.1 mrg 1558 1.1 mrg __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]); 1559 1.1 mrg QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0]; 1560 1.1 mrg 1561 1.1 mrg CA4.w[1] = CX.w[1] - QB256.w[1]; 1562 1.1 mrg CA4.w[0] = CX.w[0] - QB256.w[0]; 1563 1.1 mrg if (CX.w[0] < QB256.w[0]) 1564 1.1 mrg CA4.w[1]--; 1565 1.1 mrg if (CR.w[0] || CR.w[1]) 1566 1.1 mrg CA4.w[0] |= 1; 1567 1.1 mrg done = 1; 1568 1.1 mrg if(CA4.w[1]|CA4.w[0]) { 1569 1.1 mrg __mul_64x128_low(CY, (power10_table_128[ed2].w[0]),CY); 1570 1.1 mrg } 1571 1.1 mrg } 1572 1.1 mrg 1573 1.1 mrg } 1574 1.1 mrg 1575 1.1 mrg if (!done) { 1576 1.1 mrg __div_256_by_128 (&CQ, &CA4, CY); 1577 1.1 mrg } 1578 1.1 mrg 1579 1.1 mrg 1580 1.1 mrg 1581 1.1 mrg #ifdef SET_STATUS_FLAGS 1582 1.1 mrg if (CA4.w[0] || CA4.w[1]) { 1583 1.1 mrg // set status flags 1584 1.1 mrg __set_status_flags (pfpsf, INEXACT_EXCEPTION); 1585 1.1 mrg } 1586 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 1587 1.1 mrg else 1588 1.1 mrg #endif 1589 1.1 mrg #else 1590 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 1591 1.1 mrg if (!CA4.w[0] && !CA4.w[1]) 1592 1.1 mrg #endif 1593 1.1 mrg #endif 1594 1.1 mrg #ifndef LEAVE_TRAILING_ZEROS 1595 1.1 mrg // check whether result is exact 1596 1.1 mrg { 1597 1.1 mrg if(!done) { 1598 1.1 mrg // check whether CX, CY are short 1599 1.1 mrg if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) { 1600 1.1 mrg i = (int) CY.w[0] - 1; 1601 1.1 mrg j = (int) CX.w[0] - 1; 1602 1.1 mrg // difference in powers of 2 factors for Y and X 1603 1.1 mrg nzeros = ed2 - factors[i][0] + factors[j][0]; 1604 1.1 mrg // difference in powers of 5 factors 1605 1.1 mrg d5 = ed2 - factors[i][1] + factors[j][1]; 1606 1.1 mrg if (d5 < nzeros) 1607 1.1 mrg nzeros = d5; 1608 1.1 mrg // get P*(2^M[extra_digits])/10^extra_digits 1609 1.5 mrg __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]); 1610 1.1 mrg //__mul_128x128_to_256(P256, CQ, reciprocals10_128[nzeros]);Qh.w[1]=P256.w[3];Qh.w[0]=P256.w[2]; 1611 1.1 mrg 1612 1.1 mrg // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128 1613 1.1 mrg amount = recip_scale[nzeros]; 1614 1.1 mrg __shr_128_long (CQ, Qh, amount); 1615 1.1 mrg 1616 1.1 mrg diff_expon += nzeros; 1617 1.1 mrg } else { 1618 1.1 mrg // decompose Q as Qh*10^17 + Ql 1619 1.1 mrg //T128 = reciprocals10_128[17]; 1620 1.1 mrg Q_low = CQ.w[0]; 1621 1.1 mrg 1622 1.1 mrg { 1623 1.1 mrg tdigit[0] = Q_low & 0x3ffffff; 1624 1.1 mrg tdigit[1] = 0; 1625 1.1 mrg QX = Q_low >> 26; 1626 1.1 mrg QX32 = QX; 1627 1.1 mrg nzeros = 0; 1628 1.1 mrg 1629 1.1 mrg for (j = 0; QX32; j++, QX32 >>= 7) { 1630 1.1 mrg k = (QX32 & 127); 1631 1.1 mrg tdigit[0] += convert_table[j][k][0]; 1632 1.1 mrg tdigit[1] += convert_table[j][k][1]; 1633 1.1 mrg if (tdigit[0] >= 100000000) { 1634 1.1 mrg tdigit[0] -= 100000000; 1635 1.1 mrg tdigit[1]++; 1636 1.1 mrg } 1637 1.1 mrg } 1638 1.1 mrg 1639 1.1 mrg if (tdigit[1] >= 100000000) { 1640 1.1 mrg tdigit[1] -= 100000000; 1641 1.1 mrg if (tdigit[1] >= 100000000) 1642 1.1 mrg tdigit[1] -= 100000000; 1643 1.1 mrg } 1644 1.1 mrg 1645 1.1 mrg digit = tdigit[0]; 1646 1.1 mrg if (!digit && !tdigit[1]) 1647 1.1 mrg nzeros += 16; 1648 1.1 mrg else { 1649 1.1 mrg if (!digit) { 1650 1.1 mrg nzeros += 8; 1651 1.1 mrg digit = tdigit[1]; 1652 1.1 mrg } 1653 1.1 mrg // decompose digit 1654 1.1 mrg PD = (UINT64) digit *0x068DB8BBull; 1655 1.1 mrg digit_h = (UINT32) (PD >> 40); 1656 1.1 mrg digit_low = digit - digit_h * 10000; 1657 1.1 mrg 1658 1.1 mrg if (!digit_low) 1659 1.1 mrg nzeros += 4; 1660 1.1 mrg else 1661 1.1 mrg digit_h = digit_low; 1662 1.1 mrg 1663 1.1 mrg if (!(digit_h & 1)) 1664 1.1 mrg nzeros += 1665 1.1 mrg 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >> 1666 1.1 mrg (digit_h & 7)); 1667 1.1 mrg } 1668 1.1 mrg 1669 1.1 mrg if (nzeros) { 1670 1.1 mrg // get P*(2^M[extra_digits])/10^extra_digits 1671 1.5 mrg __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]); 1672 1.1 mrg 1673 1.1 mrg // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128 1674 1.1 mrg amount = recip_scale[nzeros]; 1675 1.1 mrg __shr_128 (CQ, Qh, amount); 1676 1.1 mrg } 1677 1.1 mrg diff_expon += nzeros; 1678 1.1 mrg 1679 1.1 mrg } 1680 1.1 mrg } 1681 1.1 mrg } 1682 1.1 mrg if(diff_expon>=0){ 1683 1.1 mrg res = 1684 1.1 mrg fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], 1685 1.1 mrg rnd_mode, pfpsf); 1686 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 1687 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 1688 1.1 mrg #endif 1689 1.1 mrg BID_RETURN (res); 1690 1.1 mrg } 1691 1.1 mrg } 1692 1.1 mrg #endif 1693 1.1 mrg 1694 1.1 mrg if(diff_expon>=0) { 1695 1.1 mrg 1696 1.1 mrg #ifdef IEEE_ROUND_NEAREST 1697 1.1 mrg // rounding 1698 1.1 mrg // 2*CA4 - CY 1699 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 1700 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 1701 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 1702 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 1703 1.1 mrg 1704 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0; 1705 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D); 1706 1.1 mrg 1707 1.1 mrg CQ.w[0] += carry64; 1708 1.1 mrg //if(CQ.w[0]<carry64) 1709 1.1 mrg //CQ.w[1] ++; 1710 1.1 mrg #else 1711 1.1 mrg #ifdef IEEE_ROUND_NEAREST_TIES_AWAY 1712 1.1 mrg // rounding 1713 1.1 mrg // 2*CA4 - CY 1714 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 1715 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 1716 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 1717 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 1718 1.1 mrg 1719 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1; 1720 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D; 1721 1.1 mrg 1722 1.1 mrg CQ.w[0] += carry64; 1723 1.1 mrg if (CQ.w[0] < carry64) 1724 1.1 mrg CQ.w[1]++; 1725 1.1 mrg #else 1726 1.1 mrg rmode = rnd_mode; 1727 1.1 mrg if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2) 1728 1.1 mrg rmode = 3 - rmode; 1729 1.1 mrg switch (rmode) { 1730 1.1 mrg case ROUNDING_TO_NEAREST: // round to nearest code 1731 1.1 mrg // rounding 1732 1.1 mrg // 2*CA4 - CY 1733 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 1734 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 1735 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 1736 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 1737 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0; 1738 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D); 1739 1.1 mrg CQ.w[0] += carry64; 1740 1.1 mrg if (CQ.w[0] < carry64) 1741 1.1 mrg CQ.w[1]++; 1742 1.1 mrg break; 1743 1.1 mrg case ROUNDING_TIES_AWAY: 1744 1.1 mrg // rounding 1745 1.1 mrg // 2*CA4 - CY 1746 1.1 mrg CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63); 1747 1.1 mrg CA4r.w[0] = CA4.w[0] + CA4.w[0]; 1748 1.1 mrg __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]); 1749 1.1 mrg CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64; 1750 1.1 mrg D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1; 1751 1.1 mrg carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D; 1752 1.1 mrg CQ.w[0] += carry64; 1753 1.1 mrg if (CQ.w[0] < carry64) 1754 1.1 mrg CQ.w[1]++; 1755 1.1 mrg break; 1756 1.1 mrg case ROUNDING_DOWN: 1757 1.1 mrg case ROUNDING_TO_ZERO: 1758 1.1 mrg break; 1759 1.1 mrg default: // rounding up 1760 1.1 mrg CQ.w[0]++; 1761 1.1 mrg if (!CQ.w[0]) 1762 1.1 mrg CQ.w[1]++; 1763 1.1 mrg break; 1764 1.1 mrg } 1765 1.1 mrg #endif 1766 1.1 mrg #endif 1767 1.1 mrg 1768 1.1 mrg 1769 1.1 mrg res = 1770 1.1 mrg fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode, 1771 1.1 mrg pfpsf); 1772 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 1773 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 1774 1.1 mrg #endif 1775 1.1 mrg BID_RETURN (res); 1776 1.1 mrg } else { 1777 1.1 mrg // UF occurs 1778 1.1 mrg 1779 1.1 mrg #ifdef SET_STATUS_FLAGS 1780 1.1 mrg if ((diff_expon + 16 < 0)) { 1781 1.1 mrg // set status flags 1782 1.1 mrg __set_status_flags (pfpsf, INEXACT_EXCEPTION); 1783 1.1 mrg } 1784 1.1 mrg #endif 1785 1.1 mrg rmode = rnd_mode; 1786 1.1 mrg res = 1787 1.1 mrg get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf); 1788 1.1 mrg #ifdef UNCHANGED_BINARY_STATUS_FLAGS 1789 1.1 mrg (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); 1790 1.1 mrg #endif 1791 1.1 mrg BID_RETURN (res); 1792 1.1 mrg 1793 1.1 mrg } 1794 1.1 mrg 1795 1.1 mrg } 1796