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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.18.0/] [newlib/] [libc/] [stdlib/] [gdtoa-gethex.c] - Blame information for rev 309

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
/****************************************************************
2
 
3
The author of this software is David M. Gay.
4
 
5
Copyright (C) 1998 by Lucent Technologies
6
All Rights Reserved
7
 
8
Permission to use, copy, modify, and distribute this software and
9
its documentation for any purpose and without fee is hereby
10
granted, provided that the above copyright notice appear in all
11
copies and that both that the copyright notice and this
12
permission notice and warranty disclaimer appear in supporting
13
documentation, and that the name of Lucent or any of its entities
14
not be used in advertising or publicity pertaining to
15
distribution of the software without specific, written prior
16
permission.
17
 
18
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25
THIS SOFTWARE.
26
 
27
****************************************************************/
28
 
29
/* Please send bug reports to David M. Gay (dmg at acm dot org,
30
 * with " at " changed at "@" and " dot " changed to ".").      */
31
 
32
#include <_ansi.h>
33
#include <reent.h>
34
#include <string.h>
35
#include "mprec.h"
36
#include "gdtoa.h"
37
#include "gd_qnan.h"
38
#include "locale.h"
39
 
40
unsigned char hexdig[256];
41
 
42
static void
43
_DEFUN (htinit, (h, s, inc),
44
        unsigned char *h _AND
45
        unsigned char *s _AND
46
        int inc)
47
{
48
        int i, j;
49
        for(i = 0; (j = s[i]) !=0; i++)
50
                h[j] = i + inc;
51
}
52
 
53
void
54
_DEFUN_VOID (hexdig_init)
55
{
56
#define USC (unsigned char *)
57
        htinit(hexdig, USC "0123456789", 0x10);
58
        htinit(hexdig, USC "abcdef", 0x10 + 10);
59
        htinit(hexdig, USC "ABCDEF", 0x10 + 10);
60
}
61
 
62
static void
63
_DEFUN(rshift, (b, k),
64
        _Bigint *b _AND
65
        int k)
66
{
67
        __ULong *x, *x1, *xe, y;
68
        int n;
69
 
70
        x = x1 = b->_x;
71
        n = k >> kshift;
72
        if (n < b->_wds) {
73
                xe = x + b->_wds;
74
                x += n;
75
                if (k &= kmask) {
76
                        n = ULbits - k;
77
                        y = *x++ >> k;
78
                        while(x < xe) {
79
                                *x1++ = (y | (*x << n)) & ALL_ON;
80
                                y = *x++ >> k;
81
                                }
82
                        if ((*x1 = y) !=0)
83
                                x1++;
84
                        }
85
                else
86
                        while(x < xe)
87
                                *x1++ = *x++;
88
                }
89
        if ((b->_wds = x1 - b->_x) == 0)
90
                b->_x[0] = 0;
91
}
92
 
93
static _Bigint *
94
_DEFUN (increment, (ptr, b),
95
        struct _reent *ptr _AND
96
        _Bigint *b)
97
{
98
        __ULong *x, *xe;
99
        _Bigint *b1;
100
#ifdef Pack_16
101
        __ULong carry = 1, y;
102
#endif
103
 
104
        x = b->_x;
105
        xe = x + b->_wds;
106
#ifdef Pack_32
107
        do {
108
                if (*x < (__ULong)0xffffffffL) {
109
                        ++*x;
110
                        return b;
111
                        }
112
                *x++ = 0;
113
                } while(x < xe);
114
#else
115
        do {
116
                y = *x + carry;
117
                carry = y >> 16;
118
                *x++ = y & 0xffff;
119
                if (!carry)
120
                        return b;
121
                } while(x < xe);
122
        if (carry)
123
#endif
124
        {
125
                if (b->_wds >= b->_maxwds) {
126
                        b1 = Balloc(ptr, b->_k+1);
127
                        Bcopy(b1, b);
128
                        Bfree(ptr, b);
129
                        b = b1;
130
                        }
131
                b->_x[b->_wds++] = 1;
132
                }
133
        return b;
134
}
135
 
136
 
137
int
138
_DEFUN(gethex, (ptr, sp, fpi, exp, bp, sign),
139
        struct _reent *ptr _AND
140
        _CONST char **sp _AND
141
        FPI *fpi _AND
142
        Long *exp _AND
143
        _Bigint **bp _AND
144
        int sign)
145
{
146
        _Bigint *b;
147
        _CONST unsigned char *decpt, *s0, *s, *s1;
148
        int esign, havedig, irv, k, n, nbits, up, zret;
149
        __ULong L, lostbits, *x;
150
        Long e, e1;
151
        unsigned char *decimalpoint = (unsigned char *)
152
                                      _localeconv_r (ptr)->decimal_point;
153
        size_t decp_len = strlen ((const char *) decimalpoint);
154
        unsigned char decp_end = decimalpoint[decp_len - 1];
155
 
156
        if (!hexdig['0'])
157
                hexdig_init();
158
        havedig = 0;
159
        s0 = *(_CONST unsigned char **)sp + 2;
160
        while(s0[havedig] == '0')
161
                havedig++;
162
        s0 += havedig;
163
        s = s0;
164
        decpt = 0;
165
        zret = 0;
166
        e = 0;
167
        if (!hexdig[*s]) {
168
                zret = 1;
169
                if (strncmp ((const char *) s, (const char *) decimalpoint,
170
                             decp_len) != 0)
171
                        goto pcheck;
172
                decpt = (s += decp_len);
173
                if (!hexdig[*s])
174
                        goto pcheck;
175
                while(*s == '0')
176
                        s++;
177
                if (hexdig[*s])
178
                        zret = 0;
179
                havedig = 1;
180
                s0 = s;
181
                }
182
        while(hexdig[*s])
183
                s++;
184
        if (strncmp ((const char *) s, (const char *) decimalpoint,
185
                     decp_len) == 0
186
            && !decpt) {
187
                decpt = (s += decp_len);
188
                while(hexdig[*s])
189
                        s++;
190
                }
191
        if (decpt)
192
                e = -(((Long)(s-decpt)) << 2);
193
 pcheck:
194
        s1 = s;
195
        switch(*s) {
196
          case 'p':
197
          case 'P':
198
                esign = 0;
199
                switch(*++s) {
200
                  case '-':
201
                        esign = 1;
202
                        /* no break */
203
                  case '+':
204
                        s++;
205
                  }
206
                if ((n = hexdig[*s]) == 0 || n > 0x19) {
207
                        s = s1;
208
                        break;
209
                        }
210
                e1 = n - 0x10;
211
                while((n = hexdig[*++s]) !=0 && n <= 0x19)
212
                        e1 = 10*e1 + n - 0x10;
213
                if (esign)
214
                        e1 = -e1;
215
                e += e1;
216
          }
217
        *sp = (char*)s;
218
        if (zret)
219
                return havedig ? STRTOG_Zero : STRTOG_NoNumber;
220
        n = s1 - s0 - 1;
221
        for(k = 0; n > 7; n >>= 1)
222
                k++;
223
        b = Balloc(ptr, k);
224
        x = b->_x;
225
        n = 0;
226
        L = 0;
227
        while(s1 > s0) {
228
                if (*--s1 == decp_end && s1 - decp_len + 1 >= s0
229
                    && strncmp ((const char *) s1 - decp_len + 1,
230
                                (const char *) decimalpoint, decp_len) == 0) {
231
                        s1 -= decp_len - 1; /* Note the --s1 above! */
232
                        continue;
233
                }
234
                if (n == 32) {
235
                        *x++ = L;
236
                        L = 0;
237
                        n = 0;
238
                        }
239
                L |= (hexdig[*s1] & 0x0f) << n;
240
                n += 4;
241
                }
242
        *x++ = L;
243
        b->_wds = n = x - b->_x;
244
        n = 32*n - hi0bits(L);
245
        nbits = fpi->nbits;
246
        lostbits = 0;
247
        x = b->_x;
248
        if (n > nbits) {
249
                n -= nbits;
250
                if (any_on(b,n)) {
251
                        lostbits = 1;
252
                        k = n - 1;
253
                        if (x[k>>kshift] & 1 << (k & kmask)) {
254
                                lostbits = 2;
255
                                if (k > 1 && any_on(b,k-1))
256
                                        lostbits = 3;
257
                                }
258
                        }
259
                rshift(b, n);
260
                e += n;
261
                }
262
        else if (n < nbits) {
263
                n = nbits - n;
264
                b = lshift(ptr, b, n);
265
                e -= n;
266
                x = b->_x;
267
                }
268
        if (e > fpi->emax) {
269
 ovfl:
270
                Bfree(ptr, b);
271
                *bp = 0;
272
                return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
273
                }
274
        irv = STRTOG_Normal;
275
        if (e < fpi->emin) {
276
                irv = STRTOG_Denormal;
277
                n = fpi->emin - e;
278
                if (n >= nbits) {
279
                        switch (fpi->rounding) {
280
                          case FPI_Round_near:
281
                                if (n == nbits && (n < 2 || any_on(b,n-1)))
282
                                        goto one_bit;
283
                                break;
284
                          case FPI_Round_up:
285
                                if (!sign)
286
                                        goto one_bit;
287
                                break;
288
                          case FPI_Round_down:
289
                                if (sign) {
290
 one_bit:
291
                                        *exp = fpi->emin;
292
                                        x[0] = b->_wds = 1;
293
                                        *bp = b;
294
                                        return STRTOG_Denormal | STRTOG_Inexhi
295
                                                | STRTOG_Underflow;
296
                                        }
297
                          }
298
                        Bfree(ptr, b);
299
                        *bp = 0;
300
                        return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow;
301
                        }
302
                k = n - 1;
303
                if (lostbits)
304
                        lostbits = 1;
305
                else if (k > 0)
306
                        lostbits = any_on(b,k);
307
                if (x[k>>kshift] & 1 << (k & kmask))
308
                        lostbits |= 2;
309
                nbits -= n;
310
                rshift(b,n);
311
                e = fpi->emin;
312
                }
313
        if (lostbits) {
314
                up = 0;
315
                switch(fpi->rounding) {
316
                  case FPI_Round_zero:
317
                        break;
318
                  case FPI_Round_near:
319
                    if ((lostbits & 2)
320
                            && ((lostbits & 1) | (x[0] & 1)))
321
                                up = 1;
322
                        break;
323
                  case FPI_Round_up:
324
                        up = 1 - sign;
325
                        break;
326
                  case FPI_Round_down:
327
                        up = sign;
328
                  }
329
                if (up) {
330
                        k = b->_wds;
331
                        b = increment(ptr, b);
332
                        x = b->_x;
333
                        if (irv == STRTOG_Denormal) {
334
                                if (nbits == fpi->nbits - 1
335
                                 && x[nbits >> kshift] & 1 << (nbits & kmask))
336
                                        irv =  STRTOG_Normal;
337
                                }
338
                        else if ((b->_wds > k)
339
                         || ((n = nbits & kmask) !=0
340
                             && (hi0bits(x[k-1]) < 32-n))) {
341
                                rshift(b,1);
342
                                if (++e > fpi->emax)
343
                                        goto ovfl;
344
                                }
345
                        irv |= STRTOG_Inexhi;
346
                        }
347
                else
348
                        irv |= STRTOG_Inexlo;
349
                }
350
        *bp = b;
351
        *exp = e;
352
        return irv;
353
}
354
 

powered by: WebSVN 2.1.0

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