fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / machine / powerpc / strtosfix16.c
blobd3cfe0781039fb20187333d1f7960ce8463a387d
1 /*
2 FUNCTION
3 <<strtosfix16>>, <<strtosfix32>>, <<strtosfix64>>---string to signed fixed point
5 INDEX
6 strtosfix16
7 INDEX
8 strtosfix32
9 INDEX
10 strtosfix64
11 INDEX
12 _strtosfix16_r
13 INDEX
14 _strtosfix32_r
15 INDEX
16 _strtosfix64_r
18 ANSI_SYNOPSIS
19 #include <stdlib.h>
20 __int16 strtosfix16 (const char *<[s]>, char **<[ptr]>);
22 __int32 strtosfix32 (const char *<[s]>, char **<[ptr]>);
24 __int64 strtosfix64 (const char *<[s]>, char **<[ptr]>);
26 __int16 _strtosfix16_r (void *<[reent]>,
27 const char *<[s]>, char **<[ptr]>);
29 __int32 _strtosfix32_r (void *<[reent]>,
30 const char *<[s]>, char **<[ptr]>);
32 __int64 _strtosfix64_r (void *<[reent]>,
33 const char *<[s]>, char **<[ptr]>);
35 TRAD_SYNOPSIS
36 #include <stdlib.h>
37 __int16 strtosfix16 (<[s]>, <[ptr]>)
38 char *<[s]>;
39 char **<[ptr]>;
41 __int32 strtosfix32 (<[s]>, <[ptr]>)
42 char *<[s]>;
43 char **<[ptr]>;
45 __int64 strtosfix64 (<[s]>, <[ptr]>)
46 char *<[s]>;
47 char **<[ptr]>;
49 __int16 _strtosfix16_r (<[reent]>, <[s]>, <[ptr]>)
50 char *<[reent]>;
51 char *<[s]>;
52 char **<[ptr]>;
54 __int32 _strtosfix32_r (<[reent]>, <[s]>, <[ptr]>)
55 char *<[reent]>;
56 char *<[s]>;
57 char **<[ptr]>;
59 __int64 _strtosfix64_r (<[reent]>, <[s]>, <[ptr]>)
60 char *<[reent]>;
61 char *<[s]>;
62 char **<[ptr]>;
64 DESCRIPTION
65 The function <<strtosfix16>> converts the string <<*<[s]>>> to
66 a fixed-point sign + 15-bits fraction representation. The function
67 follows the same rules as <<strtod>>.
69 The substring converted is the longest initial
70 subsequence of <[s]>, beginning with the first
71 non-whitespace character, that has the format:
72 .[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>]
73 The substring contains no characters if <[s]> is empty, consists
74 entirely of whitespace, or if the first non-whitespace
75 character is something other than <<+>>, <<->>, <<.>>, or a
76 digit. If the substring is empty, no conversion is done, and
77 the value of <[s]> is stored in <<*<[ptr]>>>. Otherwise,
78 the substring is converted, and a pointer to the final string
79 (which will contain at least the terminating null character of
80 <[s]>) is stored in <<*<[ptr]>>>. If you want no
81 assignment to <<*<[ptr]>>>, pass a null pointer as <[ptr]>.
83 <<strtosfix32>> is identical to <<strtosfix16>> except that it
84 converts to fixed-point sign + 31-bits fraction representation.
85 <<strtosfix64>> is also similar, except that it converts
86 to fixed-point sign + 63-bit fraction format.
88 The alternate functions <<_strtosfix16_r>>, <<_strtosfix32_r>>,
89 and <<_strtosfix64_r>> are reentrant versions.
90 The extra argument <[reent]> is a pointer to a reentrancy structure.
92 RETURNS
93 The functions return the converted substring value, if any. If
94 no conversion can be performed, then 0 is returned. If the converted
95 value is a NaN, 0 is returned and errno is set to <<EDOM>>.
96 If the converted value exceeds the maximum positive fixed-point value,
97 the output value is saturated to the maximum value and <<ERANGE>> is stored in
98 errno. If the converted value is less than the minimum fixed-point negative
99 value, then the output is saturated to the minimum value and <<ERANGE>> is stored
100 in errno. Otherwise, the converted value is returned in the
101 specified fixed-point format.
103 PORTABILITY
104 <<strtosfix16>>, <<strtosfix32>>, and <<strtosfix64>> are non-standard.
106 The OS subroutines of <<strtod>> are required.
109 #ifdef __SPE__
111 #include <_ansi.h>
112 #include <limits.h>
113 #include <errno.h>
114 #include <stdlib.h>
115 #include <reent.h>
116 #include "vfieeefp.h"
119 * Convert a string to a fixed-point (sign + 15-bits) value.
121 * Ignores `locale' stuff.
123 __int16_t
124 _DEFUN (_strtosfix16_r, (rptr, nptr, endptr),
125 struct _reent *rptr _AND
126 _CONST char *nptr _AND
127 char **endptr)
129 union double_union dbl;
130 unsigned long tmp, tmp2;
131 int exp, negexp, sign;
132 __int16_t result;
134 dbl.d = _strtod_r (rptr, nptr, endptr);
136 /* treat NAN as domain error, +/- infinity as saturation */
137 if (!finite(dbl.d))
139 if (isnan (dbl.d))
141 rptr->_errno = EDOM;
142 return 0;
144 rptr->_errno = ERANGE;
145 if (word0(dbl) & Sign_bit)
146 return SHRT_MIN;
147 return SHRT_MAX;
150 /* check for normal saturation */
151 if (dbl.d >= 1.0)
153 rptr->_errno = ERANGE;
154 return SHRT_MAX;
156 else if (dbl.d < -1.0)
158 rptr->_errno = ERANGE;
159 return SHRT_MIN;
162 /* otherwise we have normal number in range */
164 /* strip off sign and exponent */
165 sign = word0(dbl) & Sign_bit;
166 exp = ((word0(dbl) & Exp_mask) >> Exp_shift) - Bias;
167 negexp = -exp;
168 if (negexp > 15)
169 return 0;
170 /* add in implicit normalized bit */
171 tmp = word0(dbl) | Exp_msk1;
172 /* remove exponent and sign */
173 tmp <<= Ebits;
174 if (negexp != 0)
176 /* perform rounding */
177 tmp2 = tmp + (1 << (negexp - 1));
178 result = (short)(tmp2 >> (negexp + 16));
179 /* check if rounding caused carry bit which must be added into result */
180 if (tmp2 < tmp)
181 result |= (1 << (16 - negexp));
182 /* check if positive saturation has occurred because of rounding */
183 if (!sign && result < 0)
185 rptr->_errno = ERANGE;
186 return SHRT_MAX;
189 else
191 /* we have -1.0, no rounding necessary */
192 return SHRT_MIN;
195 return sign ? -result : result;
198 #ifndef _REENT_ONLY
200 __int16_t
201 _DEFUN (strtosfix16, (s, ptr, base),
202 _CONST char *s _AND
203 char **ptr)
205 return _strtosfix16_r (_REENT, s, ptr);
208 #endif
210 #endif /* __SPE__ */