OSDN Git Service

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