fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / machine / powerpc / strtosfix64.c
blob3006632a415e396554c9355ce84af1ebd084b38b
1 #ifdef __SPE__
3 #include <_ansi.h>
4 #include <limits.h>
5 #include <errno.h>
6 #include <stdlib.h>
7 #include <reent.h>
8 #include "fix64.h"
11 * Convert a string to a fixed-point (sign + 63-bits) value.
13 * Ignores `locale' stuff.
15 __int64_t
16 _DEFUN (_strtosfix64_r, (rptr, nptr, endptr),
17 struct _reent *rptr _AND
18 _CONST char *nptr _AND
19 char **endptr)
21 union long_double_union ldbl;
22 int exp, negexp, sign, ld_type;
23 __uint64_t tmp, tmp2;
24 __int64_t result = 0;
26 init(ldbl);
28 _simdstrtold ((char *)nptr, endptr, &ldbl);
30 /* treat NAN as domain error, +/- infinity as saturation */
31 ld_type = _simdldcheck (&ldbl);
32 if (ld_type != 0)
34 if (ld_type == 1)
36 rptr->_errno = EDOM;
37 return 0;
39 rptr->_errno = ERANGE;
40 if (word0(ldbl) & Sign_bit)
41 return LONG_LONG_MIN;
42 return LONG_LONG_MAX;
45 /* strip off sign and exponent */
46 sign = word0(ldbl) & Sign_bit;
47 exp = ((word0(ldbl) & Exp_mask) >> Exp_shift) - Bias;
48 negexp = -exp;
49 if (negexp > 63)
50 return 0;
51 word0(ldbl) &= ~(Exp_mask | Sign_bit);
52 /* add in implicit normalized bit */
53 word0(ldbl) |= Exp_msk1;
54 /* shift so result is contained in single word */
55 tmp = word0(ldbl) << Ebits;
56 tmp |= ((unsigned long)word1(ldbl) >> (32 - Ebits));
57 tmp <<= 32;
58 if (Ebits < 32)
59 tmp |= ((unsigned long)word1(ldbl) << Ebits);
60 tmp |= ((unsigned long)word2(ldbl) >> (32 - Ebits));
62 /* check for saturation */
63 if (sign)
65 if (exp > 0 || (exp == 0 && tmp != 0x8000000000000000LL))
67 rptr->_errno = ERANGE;
68 return LONG_LONG_MIN;
71 else
73 if (exp >= 0)
75 rptr->_errno = ERANGE;
76 return LONG_LONG_MAX;
80 /* otherwise we have normal number in range */
81 if (negexp != 0)
83 /* perform rounding */
84 tmp2 = tmp + (1 << (negexp - 1));
85 result = (long long)(tmp2 >> negexp);
86 /* check if rounding caused carry bit which must be added into result */
87 if (tmp2 < tmp)
88 result |= (1 << (64 - negexp));
89 /* check if positive saturation has occurred because of rounding */
90 if (!sign && result < 0)
92 rptr->_errno = ERANGE;
93 return LONG_LONG_MAX;
96 else
98 /* we have -1.0, no rounding necessary */
99 return LONG_LONG_MIN;
102 return sign ? -result : result;
105 #ifndef _REENT_ONLY
107 __int64_t
108 _DEFUN (strtosfix64, (s, ptr, base),
109 _CONST char *s _AND
110 char **ptr)
112 return _strtosfix64_r (_REENT, s, ptr);
115 #endif
117 #endif /* __SPE__ */