source: trunk/libs/newlib/src/newlib/libc/machine/powerpc/strtosfix64.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 (sign + 63-bits) value.
12 *
13 * Ignores `locale' stuff.
14 */
15__int64_t
16_strtosfix64_r (struct _reent *rptr,
17        const char *nptr,
18        char **endptr)
19{
20  union long_double_union ldbl;
21  int exp, negexp, sign, ld_type;
22  __uint64_t tmp, tmp2;
23  __int64_t result = 0;
24
25  init(ldbl);
26
27  _simdstrtold ((char *)nptr, endptr, &ldbl);
28
29  /* treat NAN as domain error, +/- infinity as saturation */
30  ld_type = _simdldcheck (&ldbl);
31  if (ld_type != 0)
32    {
33      if (ld_type == 1)
34        {
35          rptr->_errno = EDOM;
36          return 0;
37        }
38      rptr->_errno = ERANGE;
39      if (word0(ldbl) & Sign_bit)
40        return LONG_LONG_MIN;
41      return LONG_LONG_MAX;
42    }
43
44  /* strip off sign and exponent */
45  sign = word0(ldbl) & Sign_bit;
46  exp = ((word0(ldbl) & Exp_mask) >> Exp_shift) - Bias;
47  negexp = -exp;
48  if (negexp > 63)
49    return 0;
50  word0(ldbl) &= ~(Exp_mask | Sign_bit);
51  /* add in implicit normalized bit */
52  word0(ldbl) |= Exp_msk1;
53  /* shift so result is contained in single word */
54  tmp = word0(ldbl) << Ebits;
55  tmp |= ((unsigned long)word1(ldbl) >> (32 - Ebits));
56  tmp <<= 32;
57  if (Ebits < 32)
58    tmp |= ((unsigned long)word1(ldbl) << Ebits);
59  tmp |= ((unsigned long)word2(ldbl) >> (32 - Ebits));
60
61  /* check for saturation */
62  if (sign)
63    {
64      if (exp > 0 || (exp == 0 && tmp != 0x8000000000000000LL))
65        {
66          rptr->_errno = ERANGE;
67          return LONG_LONG_MIN;
68        }
69    }
70  else
71    {
72      if (exp >= 0)
73        {
74          rptr->_errno = ERANGE;
75          return LONG_LONG_MAX;
76        }
77    }
78
79  /* otherwise we have normal number in range */
80  if (negexp != 0)
81    {
82      /* perform rounding */
83      tmp2 = tmp + (1 << (negexp - 1));
84      result = (long long)(tmp2 >> negexp);
85      /* check if rounding caused carry bit which must be added into result */
86      if (tmp2 < tmp)
87        result |= (1 << (64 - negexp));
88      /* check if positive saturation has occurred because of rounding */
89      if (!sign && result < 0)
90        {
91          rptr->_errno = ERANGE;
92          return LONG_LONG_MAX;
93        }
94    }
95  else
96    {
97      /* we have -1.0, no rounding necessary */
98      return LONG_LONG_MIN;
99    }
100
101  return sign ? -result : result;
102}
103
104#ifndef _REENT_ONLY
105
106__int64_t
107strtosfix64 (const char *s,
108        char **ptr)
109{
110  return _strtosfix64_r (_REENT, s, ptr);
111}
112
113#endif
114
115#endif /* __SPE__ */
Note: See TracBrowser for help on using the repository browser.