Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/machine/powerpc/strtosfix16.c')
-rw-r--r--newlib/libc/machine/powerpc/strtosfix16.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/newlib/libc/machine/powerpc/strtosfix16.c b/newlib/libc/machine/powerpc/strtosfix16.c
new file mode 100644
index 000000000..ad629978c
--- /dev/null
+++ b/newlib/libc/machine/powerpc/strtosfix16.c
@@ -0,0 +1,206 @@
+/*
+FUNCTION
+ <<strtosfix16>>, <<strtosfix32>>, <<strtosfix64>>---string to signed fixed point
+
+INDEX
+ strtosfix16
+INDEX
+ strtosfix32
+INDEX
+ strtosfix64
+INDEX
+ _strtosfix16_r
+INDEX
+ _strtosfix32_r
+INDEX
+ _strtosfix64_r
+
+ANSI_SYNOPSIS
+ #include <stdlib.h>
+ __int16 strtosfix16 (const char *<[s]>, char **<[ptr]>);
+
+ __int32 strtosfix32 (const char *<[s]>, char **<[ptr]>);
+
+ __int64 strtosfix64 (const char *<[s]>, char **<[ptr]>);
+
+ __int16 _strtosfix16_r (void *<[reent]>,
+ const char *<[s]>, char **<[ptr]>);
+
+ __int32 _strtosfix32_r (void *<[reent]>,
+ const char *<[s]>, char **<[ptr]>);
+
+ __int64 _strtosfix64_r (void *<[reent]>,
+ const char *<[s]>, char **<[ptr]>);
+
+TRAD_SYNOPSIS
+ #include <stdlib.h>
+ __int16 strtosfix16 (<[s]>, <[ptr]>)
+ char *<[s]>;
+ char **<[ptr]>;
+
+ __int32 strtosfix32 (<[s]>, <[ptr]>)
+ char *<[s]>;
+ char **<[ptr]>;
+
+ __int64 strtosfix64 (<[s]>, <[ptr]>)
+ char *<[s]>;
+ char **<[ptr]>;
+
+ __int16 _strtosfix16_r (<[reent]>, <[s]>, <[ptr]>)
+ char *<[reent]>;
+ char *<[s]>;
+ char **<[ptr]>;
+
+ __int32 _strtosfix32_r (<[reent]>, <[s]>, <[ptr]>)
+ char *<[reent]>;
+ char *<[s]>;
+ char **<[ptr]>;
+
+ __int64 _strtosfix64_r (<[reent]>, <[s]>, <[ptr]>)
+ char *<[reent]>;
+ char *<[s]>;
+ char **<[ptr]>;
+
+DESCRIPTION
+ The function <<strtosfix16>> converts the string <<*<[s]>>> to
+ a fixed-point sign + 15-bits fraction representation. The function
+ follows the same rules as <<strtod>>.
+
+ The substring converted is the longest initial
+ subsequence of <[s]>, beginning with the first
+ non-whitespace character, that has the format:
+ .[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>]
+ The substring contains no characters if <[s]> is empty, consists
+ entirely of whitespace, or if the first non-whitespace
+ character is something other than <<+>>, <<->>, <<.>>, or a
+ digit. If the substring is empty, no conversion is done, and
+ the value of <[s]> is stored in <<*<[ptr]>>>. Otherwise,
+ the substring is converted, and a pointer to the final string
+ (which will contain at least the terminating null character of
+ <[s]>) is stored in <<*<[ptr]>>>. If you want no
+ assignment to <<*<[ptr]>>>, pass a null pointer as <[ptr]>.
+
+ <<strtosfix32>> is identical to <<strtosfix16>> except that it
+ converts to fixed-point sign + 31-bits fraction representation.
+ <<strtosfix64>> is also similar, except that it converts
+ to fixed-point sign + 63-bit fraction format.
+
+ The alternate functions <<_strtosfix16_r>>, <<_strtosfix32_r>>,
+ and <<_strtosfix64_r>> are reentrant versions.
+ The extra argument <[reent]> is a pointer to a reentrancy structure.
+
+RETURNS
+ The functions return the converted substring value, if any. If
+ no conversion can be performed, then 0 is returned. If the converted
+ value is a NaN, 0 is returned and errno is set to <<EDOM>>.
+ If the converted value exceeds the maximum positive fixed-point value,
+ the output value is saturated to the maximum value and <<ERANGE>> is stored in
+ errno. If the converted value is less than the minimum fixed-point negative
+ value, then the output is saturated to the minimum value and <<ERANGE>> is stored
+ in errno. Otherwise, the converted value is returned in the
+ specified fixed-point format.
+
+PORTABILITY
+ <<strtosfix16>>, <<strtosfix32>>, and <<strtosfix64>> are non-standard.
+
+ The OS subroutines of <<strtod>> are required.
+*/
+
+#include <_ansi.h>
+#include <limits.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <reent.h>
+#include "vfieeefp.h"
+
+/*
+ * Convert a string to a fixed-point (sign + 15-bits) value.
+ *
+ * Ignores `locale' stuff.
+ */
+__int16_t
+_DEFUN (_strtosfix16_r, (rptr, nptr, endptr),
+ struct _reent *rptr _AND
+ _CONST char *nptr _AND
+ char **endptr)
+{
+ union double_union dbl;
+ unsigned long tmp, tmp2;
+ int exp, negexp, sign;
+ __int16_t result;
+
+ dbl.d = _strtod_r (rptr, nptr, endptr);
+
+ /* treat NAN as domain error, +/- infinity as saturation */
+ if (!finite(dbl.d))
+ {
+ if (isnan (dbl.d))
+ {
+ rptr->_errno = EDOM;
+ return 0;
+ }
+ rptr->_errno = ERANGE;
+ if (word0(dbl) & Sign_bit)
+ return SHRT_MIN;
+ return SHRT_MAX;
+ }
+
+ /* check for normal saturation */
+ if (dbl.d >= 1.0)
+ {
+ rptr->_errno = ERANGE;
+ return SHRT_MAX;
+ }
+ else if (dbl.d < -1.0)
+ {
+ rptr->_errno = ERANGE;
+ return SHRT_MIN;
+ }
+
+ /* otherwise we have normal number in range */
+
+ /* strip off sign and exponent */
+ sign = word0(dbl) & Sign_bit;
+ exp = ((word0(dbl) & Exp_mask) >> Exp_shift) - Bias;
+ negexp = -exp;
+ if (negexp > 15)
+ return 0;
+ /* add in implicit normalized bit */
+ tmp = word0(dbl) | Exp_msk1;
+ /* remove exponent and sign */
+ tmp <<= Ebits;
+ if (negexp != 0)
+ {
+ /* perform rounding */
+ tmp2 = tmp + (1 << (negexp - 1));
+ result = (short)(tmp2 >> (negexp + 16));
+ /* check if rounding caused carry bit which must be added into result */
+ if (tmp2 < tmp)
+ result |= (1 << (16 - negexp));
+ /* check if positive saturation has occurred because of rounding */
+ if (!sign && result < 0)
+ {
+ rptr->_errno = ERANGE;
+ return SHRT_MAX;
+ }
+ }
+ else
+ {
+ /* we have -1.0, no rounding necessary */
+ return SHRT_MIN;
+ }
+
+ return sign ? -result : result;
+}
+
+#ifndef _REENT_ONLY
+
+__int16_t
+_DEFUN (strtosfix16, (s, ptr, base),
+ _CONST char *s _AND
+ char **ptr)
+{
+ return _strtosfix16_r (_REENT, s, ptr);
+}
+
+#endif