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