source: trunk/libs/newlib/src/newlib/libc/machine/powerpc/strtoufix64.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 2.3 KB
Line 
1#ifdef __SPE__
2
3#include <_ansi.h>
4#include <limits.h>
5#include <errno.h>
6#include <stdlib.h>
7#include <reent.h>
8#include "fix64.h"
9
10/*
11 * Convert a string to a fixed-point 64-bit unsigned value.
12 *
13 * Ignores `locale' stuff.
14 */
15__uint64_t
16_strtoufix64_r (struct _reent *rptr,
17        const char *nptr,
18        char **endptr)
19{
20  union long_double_union ldbl;
21  int exp, sign, negexp, ld_type;
22  __uint64_t tmp, tmp2, result = 0;
23
24  init(ldbl);
25
26  _simdstrtold ((char *)nptr, endptr, &ldbl);
27
28  /* treat NAN as domain error, +/- infinity as saturation */
29  ld_type = _simdldcheck (&ldbl);
30  if (ld_type != 0)
31    {
32      if (ld_type == 1)
33        {
34          rptr->_errno = EDOM;
35          return 0;
36        }
37      rptr->_errno = ERANGE;
38      if (word0(ldbl) & Sign_bit)
39        return 0;
40      return ULONG_LONG_MAX;
41    }
42
43  /* strip off sign and exponent */
44  sign = word0(ldbl) & Sign_bit;
45  exp = ((word0(ldbl) & Exp_mask) >> Exp_shift) - Bias;
46  negexp = -exp;
47  if (negexp > 63)
48    return 0;
49  word0(ldbl) &= ~(Exp_mask | Sign_bit);
50  /* add in implicit normalized bit */
51  word0(ldbl) |= Exp_msk1;
52  /* shift so result is contained in single word */
53  tmp = word0(ldbl) << Ebits;
54  tmp |= ((unsigned long)word1(ldbl) >> (32 - Ebits));
55  tmp <<= 32;
56  if (Ebits < 32)
57    tmp |= ((unsigned long)word1(ldbl) << Ebits);
58  tmp |= ((unsigned long)word2(ldbl) >> (32 - Ebits));
59
60  /* check for saturation */
61  if (sign)
62    {
63      rptr->_errno = ERANGE;
64      return 0;
65    }
66  else
67    {
68      if (exp > 0 || (exp == 0 && tmp >= 0x8000000000000000LL))
69        {
70          rptr->_errno = ERANGE;
71          return ULONG_LONG_MAX;
72        }
73    }
74
75  /* otherwise we have normal number in range */
76  if (negexp > 1)
77    {
78      tmp2 = tmp + (1 << (negexp - 2));
79      result = (tmp2 >> (negexp - 1));
80      /* if rounding causes carry, add carry bit in */
81      if (tmp2 < tmp)
82        result += 1 << (64 - negexp);
83    }
84  else
85    {
86      if (Ebits < 32)
87        {
88          result = tmp + ((word2(ldbl) & (1 << (32 - Ebits - 1))) != 0);
89          /* if rounding causes carry, then saturation has occurred */
90          if (result < tmp)
91            {
92              rptr->_errno = ERANGE;
93              return ULONG_LONG_MAX;
94            }
95        }
96      else
97        result = tmp;
98    }
99
100  return result;
101}
102
103#ifndef _REENT_ONLY
104
105__uint64_t
106strtoufix64 (const char *s,
107        char **ptr)
108{
109  return _strtoufix64_r (_REENT, s, ptr);
110}
111
112#endif
113
114#endif /* __SPE__ */
Note: See TracBrowser for help on using the repository browser.