OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [libbid/] [bid128_string.c] - Blame information for rev 734

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 734 jeremybenn
/* 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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.