1/* Copyright (C) 2007-2022 Free Software Foundation, Inc. 2 3This file is part of GCC. 4 5GCC is free software; you can redistribute it and/or modify it under 6the terms of the GNU General Public License as published by the Free 7Software Foundation; either version 3, or (at your option) any later 8version. 9 10GCC is distributed in the hope that it will be useful, but WITHOUT ANY 11WARRANTY; without even the implied warranty of MERCHANTABILITY or 12FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13for more details. 14 15Under Section 7 of GPL version 3, you are granted additional 16permissions described in the GCC Runtime Library Exception, version 173.1, as published by the Free Software Foundation. 18 19You should have received a copy of the GNU General Public License and 20a copy of the GCC Runtime Library Exception along with this program; 21see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 22<http://www.gnu.org/licenses/>. */ 23 24/***************************************************************************** 25 * BID128_to_string 26 ****************************************************************************/ 27 28#define BID_128RES 29#include <stdio.h> 30#include "bid_internal.h" 31#include "bid128_2_str.h" 32#include "bid128_2_str_macros.h" 33 34extern int bid128_coeff_2_string (UINT64 X_hi, UINT64 X_lo, 35 char *char_ptr); 36 37#if DECIMAL_CALL_BY_REFERENCE 38 39void 40bid128_to_string (char *str, 41 UINT128 * 42 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM 43 _EXC_INFO_PARAM) { 44 UINT128 x; 45#else 46 47void 48bid128_to_string (char *str, UINT128 x 49 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 50#endif 51 UINT64 x_sign; 52 UINT64 x_exp; 53 int exp; // unbiased exponent 54 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64) 55 int ind; 56 UINT128 C1; 57 unsigned int k = 0; // pointer in the string 58 unsigned int d0, d123; 59 UINT64 HI_18Dig, LO_18Dig, Tmp; 60 UINT32 MiDi[12], *ptr; 61 char *c_ptr_start, *c_ptr; 62 int midi_ind, k_lcv, len; 63 64#if DECIMAL_CALL_BY_REFERENCE 65 x = *px; 66#endif 67 68 BID_SWAP128(x); 69 // check for NaN or Infinity 70 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 71 // x is special 72 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN 73 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN 74 // set invalid flag 75 str[0] = ((SINT64)x.w[1]<0)? '-':'+'; 76 str[1] = 'S'; 77 str[2] = 'N'; 78 str[3] = 'a'; 79 str[4] = 'N'; 80 str[5] = '\0'; 81 } else { // x is QNaN 82 str[0] = ((SINT64)x.w[1]<0)? '-':'+'; 83 str[1] = 'Q'; 84 str[2] = 'N'; 85 str[3] = 'a'; 86 str[4] = 'N'; 87 str[5] = '\0'; 88 } 89 } else { // x is not a NaN, so it must be infinity 90 if ((x.w[1] & MASK_SIGN) == 0x0ull) { // x is +inf 91 str[0] = '+'; 92 str[1] = 'I'; 93 str[2] = 'n'; 94 str[3] = 'f'; 95 str[4] = '\0'; 96 } else { // x is -inf 97 str[0] = '-'; 98 str[1] = 'I'; 99 str[2] = 'n'; 100 str[3] = 'f'; 101 str[4] = '\0'; 102 } 103 } 104 return; 105 } else if (((x.w[1] & MASK_COEFF) == 0x0ull) && (x.w[0] == 0x0ull)) { 106 // x is 0 107 len = 0; 108 109 //determine if +/- 110 if (x.w[1] & MASK_SIGN) 111 str[len++] = '-'; 112 else 113 str[len++] = '+'; 114 str[len++] = '0'; 115 str[len++] = 'E'; 116 117 // extract the exponent and print 118 exp = (int) (((x.w[1] & MASK_EXP) >> 49) - 6176); 119 if(exp > (((0x5ffe)>>1) - (6176))) { 120 exp = (int) ((((x.w[1]<<2) & MASK_EXP) >> 49) - 6176); 121 } 122 if (exp >= 0) { 123 str[len++] = '+'; 124 len += sprintf (str + len, "%u", exp);// should not use sprintf (should 125 // use sophisticated algorithm, since we know range of exp is limited) 126 str[len++] = '\0'; 127 } else { 128 len += sprintf (str + len, "%d", exp);// should not use sprintf (should 129 // use sophisticated algorithm, since we know range of exp is limited) 130 str[len++] = '\0'; 131 } 132 return; 133 } else { // x is not special and is not zero 134 // unpack x 135 x_sign = x.w[1] & MASK_SIGN;// 0 for positive, MASK_SIGN for negative 136 x_exp = x.w[1] & MASK_EXP;// biased and shifted left 49 bit positions 137 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) 138 x_exp = (x.w[1]<<2) & MASK_EXP;// biased and shifted left 49 bit positions 139 C1.w[1] = x.w[1] & MASK_COEFF; 140 C1.w[0] = x.w[0]; 141 exp = (x_exp >> 49) - 6176; 142 143 // determine sign's representation as a char 144 if (x_sign) 145 str[k++] = '-';// negative number 146 else 147 str[k++] = '+';// positive number 148 149 // determine coefficient's representation as a decimal string 150 151 // if zero or non-canonical, set coefficient to '0' 152 if ((C1.w[1] > 0x0001ed09bead87c0ull) || 153 (C1.w[1] == 0x0001ed09bead87c0ull && 154 (C1.w[0] > 0x378d8e63ffffffffull)) || 155 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) || 156 ((C1.w[1] == 0) && (C1.w[0] == 0))) { 157 str[k++] = '0'; 158 } else { 159 /* **************************************************** 160 This takes a bid coefficient in C1.w[1],C1.w[0] 161 and put the converted character sequence at location 162 starting at &(str[k]). The function returns the number 163 of MiDi returned. Note that the character sequence 164 does not have leading zeros EXCEPT when the input is of 165 zero value. It will then output 1 character '0' 166 The algorithm essentailly tries first to get a sequence of 167 Millenial Digits "MiDi" and then uses table lookup to get the 168 character strings of these MiDis. 169 **************************************************** */ 170 /* Algorithm first decompose possibly 34 digits in hi and lo 171 18 digits. (The high can have at most 16 digits). It then 172 uses macro that handle 18 digit portions. 173 The first step is to get hi and lo such that 174 2^(64) C1.w[1] + C1.w[0] = hi * 10^18 + lo, 0 <= lo < 10^18. 175 We use a table lookup method to obtain the hi and lo 18 digits. 176 [C1.w[1],C1.w[0]] = c_8 2^(107) + c_7 2^(101) + ... + c_0 2^(59) + d 177 where 0 <= d < 2^59 and each c_j has 6 bits. Because d fits in 178 18 digits, we set hi = 0, and lo = d to begin with. 179 We then retrieve from a table, for j = 0, 1, ..., 8 180 that gives us A and B where c_j 2^(59+6j) = A * 10^18 + B. 181 hi += A ; lo += B; After each accumulation into lo, we normalize 182 immediately. So at the end, we have the decomposition as we need. */ 183 184 Tmp = C1.w[0] >> 59; 185 LO_18Dig = (C1.w[0] << 5) >> 5; 186 Tmp += (C1.w[1] << 5); 187 HI_18Dig = 0; 188 k_lcv = 0; 189 // Tmp = {C1.w[1]{49:0}, C1.w[0]{63:59}} 190 // Lo_18Dig = {C1.w[0]{58:0}} 191 192 while (Tmp) { 193 midi_ind = (int) (Tmp & 0x000000000000003FLL); 194 midi_ind <<= 1; 195 Tmp >>= 6; 196 HI_18Dig += mod10_18_tbl[k_lcv][midi_ind++]; 197 LO_18Dig += mod10_18_tbl[k_lcv++][midi_ind]; 198 __L0_Normalize_10to18 (HI_18Dig, LO_18Dig); 199 } 200 ptr = MiDi; 201 if (HI_18Dig == 0LL) { 202 __L1_Split_MiDi_6_Lead (LO_18Dig, ptr); 203 } else { 204 __L1_Split_MiDi_6_Lead (HI_18Dig, ptr); 205 __L1_Split_MiDi_6 (LO_18Dig, ptr); 206 } 207 len = ptr - MiDi; 208 c_ptr_start = &(str[k]); 209 c_ptr = c_ptr_start; 210 211 /* now convert the MiDi into character strings */ 212 __L0_MiDi2Str_Lead (MiDi[0], c_ptr); 213 for (k_lcv = 1; k_lcv < len; k_lcv++) { 214 __L0_MiDi2Str (MiDi[k_lcv], c_ptr); 215 } 216 k = k + (c_ptr - c_ptr_start); 217 } 218 219 // print E and sign of exponent 220 str[k++] = 'E'; 221 if (exp < 0) { 222 exp = -exp; 223 str[k++] = '-'; 224 } else { 225 str[k++] = '+'; 226 } 227 228 // determine exponent's representation as a decimal string 229 // d0 = exp / 1000; 230 // Use Property 1 231 d0 = (exp * 0x418a) >> 24;// 0x418a * 2^-24 = (10^(-3))RP,15 232 d123 = exp - 1000 * d0; 233 234 if (d0) { // 1000 <= exp <= 6144 => 4 digits to return 235 str[k++] = d0 + 0x30;// ASCII for decimal digit d0 236 ind = 3 * d123; 237 str[k++] = char_table3[ind]; 238 str[k++] = char_table3[ind + 1]; 239 str[k++] = char_table3[ind + 2]; 240 } else { // 0 <= exp <= 999 => d0 = 0 241 if (d123 < 10) { // 0 <= exp <= 9 => 1 digit to return 242 str[k++] = d123 + 0x30;// ASCII 243 } else if (d123 < 100) { // 10 <= exp <= 99 => 2 digits to return 244 ind = 2 * (d123 - 10); 245 str[k++] = char_table2[ind]; 246 str[k++] = char_table2[ind + 1]; 247 } else { // 100 <= exp <= 999 => 3 digits to return 248 ind = 3 * d123; 249 str[k++] = char_table3[ind]; 250 str[k++] = char_table3[ind + 1]; 251 str[k++] = char_table3[ind + 2]; 252 } 253 } 254 str[k] = '\0'; 255 256 } 257 return; 258 259} 260 261 262#define MAX_FORMAT_DIGITS_128 34 263#define MAX_STRING_DIGITS_128 100 264#define MAX_SEARCH MAX_STRING_DIGITS_128-MAX_FORMAT_DIGITS_128-1 265 266 267#if DECIMAL_CALL_BY_REFERENCE 268 269void 270bid128_from_string (UINT128 * pres, 271 char *ps _RND_MODE_PARAM _EXC_FLAGS_PARAM 272 _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 273#else 274 275UINT128 276bid128_from_string (char *ps _RND_MODE_PARAM _EXC_FLAGS_PARAM 277 _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 278#endif 279 UINT128 CX, res; 280 UINT64 sign_x, coeff_high, coeff_low, coeff2, coeff_l2, carry = 0x0ull, 281 scale_high, right_radix_leading_zeros; 282 int ndigits_before, ndigits_after, ndigits_total, dec_expon, sgn_exp, 283 i, d2, rdx_pt_enc; 284 char c, buffer[MAX_STRING_DIGITS_128]; 285 int save_rnd_mode; 286 int save_fpsf; 287 288#if DECIMAL_CALL_BY_REFERENCE 289#if !DECIMAL_GLOBAL_ROUNDING 290 _IDEC_round rnd_mode = *prnd_mode; 291#endif 292#endif 293 294 save_rnd_mode = rnd_mode; // dummy 295 save_fpsf = *pfpsf; // dummy 296 297 right_radix_leading_zeros = rdx_pt_enc = 0; 298 299 // if null string, return NaN 300 if (!ps) { 301 res.w[1] = 0x7c00000000000000ull; 302 res.w[0] = 0; 303 BID_RETURN (res); 304 } 305 // eliminate leading white space 306 while ((*ps == ' ') || (*ps == '\t')) 307 ps++; 308 309 // c gets first character 310 c = *ps; 311 312 313 // if c is null or not equal to a (radix point, negative sign, 314 // positive sign, or number) it might be SNaN, sNaN, Infinity 315 if (!c 316 || (c != '.' && c != '-' && c != '+' 317 && ((unsigned) (c - '0') > 9))) { 318 res.w[0] = 0; 319 // Infinity? 320 if ((tolower_macro (ps[0]) == 'i' && tolower_macro (ps[1]) == 'n' 321 && tolower_macro (ps[2]) == 'f') 322 && (!ps[3] 323 || (tolower_macro (ps[3]) == 'i' 324 && tolower_macro (ps[4]) == 'n' 325 && tolower_macro (ps[5]) == 'i' 326 && tolower_macro (ps[6]) == 't' 327 && tolower_macro (ps[7]) == 'y' && !ps[8]) 328 )) { 329 res.w[1] = 0x7800000000000000ull; 330 BID_RETURN (res); 331 } 332 // return sNaN 333 if (tolower_macro (ps[0]) == 's' && tolower_macro (ps[1]) == 'n' && 334 tolower_macro (ps[2]) == 'a' && tolower_macro (ps[3]) == 'n') { 335 // case insensitive check for snan 336 res.w[1] = 0x7e00000000000000ull; 337 BID_RETURN (res); 338 } else { 339 // return qNaN 340 res.w[1] = 0x7c00000000000000ull; 341 BID_RETURN (res); 342 } 343 } 344 // if +Inf, -Inf, +Infinity, or -Infinity (case insensitive check for inf) 345 if ((tolower_macro (ps[1]) == 'i' && tolower_macro (ps[2]) == 'n' && 346 tolower_macro (ps[3]) == 'f') && (!ps[4] || 347 (tolower_macro (ps[4]) == 'i' && tolower_macro (ps[5]) == 'n' && 348 tolower_macro (ps[6]) == 'i' && tolower_macro (ps[7]) == 't' && 349 tolower_macro (ps[8]) == 'y' && !ps[9]))) { // ci check for infinity 350 res.w[0] = 0; 351 352 if (c == '+') 353 res.w[1] = 0x7800000000000000ull; 354 else if (c == '-') 355 res.w[1] = 0xf800000000000000ull; 356 else 357 res.w[1] = 0x7c00000000000000ull; 358 359 BID_RETURN (res); 360 } 361 // if +sNaN, +SNaN, -sNaN, or -SNaN 362 if (tolower_macro (ps[1]) == 's' && tolower_macro (ps[2]) == 'n' 363 && tolower_macro (ps[3]) == 'a' && tolower_macro (ps[4]) == 'n') { 364 res.w[0] = 0; 365 if (c == '-') 366 res.w[1] = 0xfe00000000000000ull; 367 else 368 res.w[1] = 0x7e00000000000000ull; 369 BID_RETURN (res); 370 } 371 // set up sign_x to be OR'ed with the upper word later 372 if (c == '-') 373 sign_x = 0x8000000000000000ull; 374 else 375 sign_x = 0; 376 377 // go to next character if leading sign 378 if (c == '-' || c == '+') 379 ps++; 380 381 c = *ps; 382 383 // if c isn't a decimal point or a decimal digit, return NaN 384 if (c != '.' && ((unsigned) (c - '0') > 9)) { 385 res.w[1] = 0x7c00000000000000ull | sign_x; 386 res.w[0] = 0; 387 BID_RETURN (res); 388 } 389 // detect zero (and eliminate/ignore leading zeros) 390 if (*(ps) == '0') { 391 392 // if all numbers are zeros (with possibly 1 radix point, the number is zero 393 // should catch cases such as: 000.0 394 while (*ps == '0') { 395 396 ps++; 397 398 // for numbers such as 0.0000000000000000000000000000000000001001, 399 // we want to count the leading zeros 400 if (rdx_pt_enc) { 401 right_radix_leading_zeros++; 402 } 403 // if this character is a radix point, make sure we haven't already 404 // encountered one 405 if (*(ps) == '.') { 406 if (rdx_pt_enc == 0) { 407 rdx_pt_enc = 1; 408 // if this is the first radix point, and the next character is NULL, 409 // we have a zero 410 if (!*(ps + 1)) { 411 res.w[1] = 412 (0x3040000000000000ull - 413 (right_radix_leading_zeros << 49)) | sign_x; 414 res.w[0] = 0; 415 BID_RETURN (res); 416 } 417 ps = ps + 1; 418 } else { 419 // if 2 radix points, return NaN 420 res.w[1] = 0x7c00000000000000ull | sign_x; 421 res.w[0] = 0; 422 BID_RETURN (res); 423 } 424 } else if (!*(ps)) { 425 //res.w[1] = 0x3040000000000000ull | sign_x; 426 res.w[1] = 427 (0x3040000000000000ull - 428 (right_radix_leading_zeros << 49)) | sign_x; 429 res.w[0] = 0; 430 BID_RETURN (res); 431 } 432 } 433 } 434 435 c = *ps; 436 437 // initialize local variables 438 ndigits_before = ndigits_after = ndigits_total = 0; 439 sgn_exp = 0; 440 // pstart_coefficient = ps; 441 442 if (!rdx_pt_enc) { 443 // investigate string (before radix point) 444 while ((unsigned) (c - '0') <= 9 445 && ndigits_before < MAX_STRING_DIGITS_128) { 446 buffer[ndigits_before] = c; 447 ps++; 448 c = *ps; 449 ndigits_before++; 450 } 451 452 ndigits_total = ndigits_before; 453 if (c == '.') { 454 ps++; 455 if ((c = *ps)) { 456 457 // investigate string (after radix point) 458 while ((unsigned) (c - '0') <= 9 459 && ndigits_total < MAX_STRING_DIGITS_128) { 460 buffer[ndigits_total] = c; 461 ps++; 462 c = *ps; 463 ndigits_total++; 464 } 465 ndigits_after = ndigits_total - ndigits_before; 466 } 467 } 468 } else { 469 // we encountered a radix point while detecting zeros 470 //if (c = *ps){ 471 472 c = *ps; 473 ndigits_total = 0; 474 // investigate string (after radix point) 475 while ((unsigned) (c - '0') <= 9 476 && ndigits_total < MAX_STRING_DIGITS_128) { 477 buffer[ndigits_total] = c; 478 ps++; 479 c = *ps; 480 ndigits_total++; 481 } 482 ndigits_after = ndigits_total - ndigits_before; 483 } 484 485 // get exponent 486 dec_expon = 0; 487 if (ndigits_total < MAX_STRING_DIGITS_128) { 488 if (c) { 489 if (c != 'e' && c != 'E') { 490 // return NaN 491 res.w[1] = 0x7c00000000000000ull; 492 res.w[0] = 0; 493 BID_RETURN (res); 494 } 495 ps++; 496 c = *ps; 497 498 if (((unsigned) (c - '0') > 9) 499 && ((c != '+' && c != '-') || (unsigned) (ps[1] - '0') > 9)) { 500 // return NaN 501 res.w[1] = 0x7c00000000000000ull; 502 res.w[0] = 0; 503 BID_RETURN (res); 504 } 505 506 if (c == '-') { 507 sgn_exp = -1; 508 ps++; 509 c = *ps; 510 } else if (c == '+') { 511 ps++; 512 c = *ps; 513 } 514 515 dec_expon = c - '0'; 516 i = 1; 517 ps++; 518 c = *ps - '0'; 519 while (((unsigned) c) <= 9 && i < 7) { 520 d2 = dec_expon + dec_expon; 521 dec_expon = (d2 << 2) + d2 + c; 522 ps++; 523 c = *ps - '0'; 524 i++; 525 } 526 } 527 528 dec_expon = (dec_expon + sgn_exp) ^ sgn_exp; 529 } 530 531 532 if (ndigits_total <= MAX_FORMAT_DIGITS_128) { 533 dec_expon += 534 DECIMAL_EXPONENT_BIAS_128 - ndigits_after - 535 right_radix_leading_zeros; 536 if (dec_expon < 0) { 537 res.w[1] = 0 | sign_x; 538 res.w[0] = 0; 539 } 540 if (ndigits_total == 0) { 541 CX.w[0] = 0; 542 CX.w[1] = 0; 543 } else if (ndigits_total <= 19) { 544 coeff_high = buffer[0] - '0'; 545 for (i = 1; i < ndigits_total; i++) { 546 coeff2 = coeff_high + coeff_high; 547 coeff_high = (coeff2 << 2) + coeff2 + buffer[i] - '0'; 548 } 549 CX.w[0] = coeff_high; 550 CX.w[1] = 0; 551 } else { 552 coeff_high = buffer[0] - '0'; 553 for (i = 1; i < ndigits_total - 17; i++) { 554 coeff2 = coeff_high + coeff_high; 555 coeff_high = (coeff2 << 2) + coeff2 + buffer[i] - '0'; 556 } 557 coeff_low = buffer[i] - '0'; 558 i++; 559 for (; i < ndigits_total; i++) { 560 coeff_l2 = coeff_low + coeff_low; 561 coeff_low = (coeff_l2 << 2) + coeff_l2 + buffer[i] - '0'; 562 } 563 // now form the coefficient as coeff_high*10^19+coeff_low+carry 564 scale_high = 100000000000000000ull; 565 __mul_64x64_to_128_fast (CX, coeff_high, scale_high); 566 567 CX.w[0] += coeff_low; 568 if (CX.w[0] < coeff_low) 569 CX.w[1]++; 570 } 571 get_BID128 (&res, sign_x, dec_expon, CX,&rnd_mode,pfpsf); 572 BID_RETURN (res); 573 } else { 574 // simply round using the digits that were read 575 576 dec_expon += 577 ndigits_before + DECIMAL_EXPONENT_BIAS_128 - 578 MAX_FORMAT_DIGITS_128 - right_radix_leading_zeros; 579 580 if (dec_expon < 0) { 581 res.w[1] = 0 | sign_x; 582 res.w[0] = 0; 583 } 584 585 coeff_high = buffer[0] - '0'; 586 for (i = 1; i < MAX_FORMAT_DIGITS_128 - 17; i++) { 587 coeff2 = coeff_high + coeff_high; 588 coeff_high = (coeff2 << 2) + coeff2 + buffer[i] - '0'; 589 } 590 coeff_low = buffer[i] - '0'; 591 i++; 592 for (; i < MAX_FORMAT_DIGITS_128; i++) { 593 coeff_l2 = coeff_low + coeff_low; 594 coeff_low = (coeff_l2 << 2) + coeff_l2 + buffer[i] - '0'; 595 } 596 switch(rnd_mode) { 597 case ROUNDING_TO_NEAREST: 598 carry = ((unsigned) ('4' - buffer[i])) >> 31; 599 if ((buffer[i] == '5' && !(coeff_low & 1)) || dec_expon < 0) { 600 if (dec_expon >= 0) { 601 carry = 0; 602 i++; 603 } 604 for (; i < ndigits_total; i++) { 605 if (buffer[i] > '0') { 606 carry = 1; 607 break; 608 } 609 } 610 } 611 break; 612 613 case ROUNDING_DOWN: 614 if(sign_x) 615 for (; i < ndigits_total; i++) { 616 if (buffer[i] > '0') { 617 carry = 1; 618 break; 619 } 620 } 621 break; 622 case ROUNDING_UP: 623 if(!sign_x) 624 for (; i < ndigits_total; i++) { 625 if (buffer[i] > '0') { 626 carry = 1; 627 break; 628 } 629 } 630 break; 631 case ROUNDING_TO_ZERO: 632 carry=0; 633 break; 634 case ROUNDING_TIES_AWAY: 635 carry = ((unsigned) ('4' - buffer[i])) >> 31; 636 if (dec_expon < 0) { 637 for (; i < ndigits_total; i++) { 638 if (buffer[i] > '0') { 639 carry = 1; 640 break; 641 } 642 } 643 } 644 break; 645 646 647 } 648 // now form the coefficient as coeff_high*10^17+coeff_low+carry 649 scale_high = 100000000000000000ull; 650 if (dec_expon < 0) { 651 if (dec_expon > -MAX_FORMAT_DIGITS_128) { 652 scale_high = 1000000000000000000ull; 653 coeff_low = (coeff_low << 3) + (coeff_low << 1); 654 dec_expon--; 655 } 656 if (dec_expon == -MAX_FORMAT_DIGITS_128 657 && coeff_high > 50000000000000000ull) 658 carry = 0; 659 } 660 661 __mul_64x64_to_128_fast (CX, coeff_high, scale_high); 662 663 coeff_low += carry; 664 CX.w[0] += coeff_low; 665 if (CX.w[0] < coeff_low) 666 CX.w[1]++; 667 668 669 get_BID128(&res, sign_x, dec_expon, CX, &rnd_mode, pfpsf); 670 BID_RETURN (res); 671 } 672} 673