Cygwin: access: Fix X_OK behaviour for backup operators and admins
[newlib-cygwin.git] / newlib / libc / machine / powerpc / strtoufix32.c
blob4340c711f69fe09e75ccea141b0a17f343e186f0
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 "vfieeefp.h"
11 * Convert a string to a fixed-point 32-bit value.
13 * Ignores `locale' stuff.
15 __uint32_t
16 _strtoufix32_r (struct _reent *rptr,
17 const char *nptr,
18 char **endptr)
20 union double_union dbl;
21 int exp, negexp;
22 __uint32_t tmp, tmp2, result = 0;
24 dbl.d = _strtod_r (rptr, nptr, endptr);
26 /* treat NAN as domain error, +/- infinity as saturation */
27 if (!finite(dbl.d))
29 if (isnan (dbl.d))
31 _REENT_ERRNO(rptr) = EDOM;
32 return 0;
34 _REENT_ERRNO(rptr) = ERANGE;
35 if (word0(dbl) & Sign_bit)
36 return 0;
37 return ULONG_MAX;
40 /* check for normal saturation */
41 if (dbl.d >= 1.0)
43 _REENT_ERRNO(rptr) = ERANGE;
44 return ULONG_MAX;
46 else if (dbl.d < 0)
48 _REENT_ERRNO(rptr) = ERANGE;
49 return 0;
52 /* otherwise we have normal positive number in range */
54 /* strip off exponent */
55 exp = ((word0(dbl) & Exp_mask) >> Exp_shift) - Bias;
56 negexp = -exp;
57 if (negexp > 32)
58 return 0;
59 word0(dbl) &= ~(Exp_mask | Sign_bit);
60 /* add in implicit normalized bit */
61 word0(dbl) |= Exp_msk1;
62 /* shift so result is contained left-justified in word */
63 tmp = word0(dbl) << Ebits;
64 tmp |= ((unsigned long)word1(dbl) >> (32 - Ebits));
65 /* perform rounding */
66 if (negexp > 1)
68 tmp2 = tmp + (1 << (negexp - 2));
69 result = (tmp2 >> (negexp - 1));
70 /* if rounding causes carry, add carry bit in */
71 if (tmp2 < tmp)
72 result += 1 << (32 - negexp);
74 else
76 result = tmp + ((word1(dbl) & (1 << (32 - Ebits - 1))) != 0);
77 /* if rounding causes carry, then saturation has occurred */
78 if (result < tmp)
80 _REENT_ERRNO(rptr) = ERANGE;
81 return ULONG_MAX;
85 return result;
88 #ifndef _REENT_ONLY
90 __uint32_t
91 strtoufix32 (const char *s,
92 char **ptr)
94 return _strtoufix32_r (_REENT, s, ptr);
97 #endif
99 #endif /* __SPE__ */