OSDN Git Service

* trans-decl.c (gfc_build_qualified_array): Don't skip generation
[pf3gnuchains/gcc-fork.git] / libgcc / config / libbid / bid128_string.c
1 /* Copyright (C) 2007, 2009  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 3, or (at your option) any later
8 version.
9
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 for more details.
14
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
18
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see 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
34 extern int bid128_coeff_2_string (UINT64 X_hi, UINT64 X_lo,
35                                   char *char_ptr);
36
37 #if DECIMAL_CALL_BY_REFERENCE
38
39 void
40 bid128_to_string (char *str,
41                   UINT128 *
42                   px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
43                   _EXC_INFO_PARAM) {
44   UINT128 x;
45 #else
46
47 void
48 bid128_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
269 void
270 bid128_from_string (UINT128 * pres,
271                     char *ps _RND_MODE_PARAM _EXC_FLAGS_PARAM
272                     _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
273 #else
274
275 UINT128
276 bid128_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 }