2002-08-17 Jeff Johnston <jjohnstn@redhat.com>

* configure.host: Add powerpc*-*-eabispe* configuration.
        * libc/machine/powerpc/atosfix16.c: New fixed-point conversion file.
        * libc/machine/powerpc/atosfix32.c: Ditto.
        * libc/machine/powerpc/atosfix64.c: Ditto.
        * libc/machine/powerpc/atoufix16.c: Ditto.
        * libc/machine/powerpc/atoufix32.c: Ditto.
        * libc/machine/powerpc/atoufix64.c: Ditto.
        * libc/machine/powerpc/fix64.h: Ditto.
        * libc/machine/powerpc/simdldtoa.c: Ditto.
        * libc/machine/powerpc/strtosfix16.c: Ditto.
        * libc/machine/powerpc/strtosfix32.c: Ditto.
        * libc/machine/powerpc/strtosfix64.c: Ditto.
        * libc/machine/powerpc/strtoufix16.c: Ditto.
        * libc/machine/powerpc/strtoufix32.c: Ditto.
        * libc/machine/powerpc/strtoufix64.c: Ditto.
        * libc/machine/powerpc/ufix64toa.c: Ditto.
        * libc/machine/powerpc/configure.in: Add check for
        powerpc*-eabispe and add fixed-point conversion functions.
        * libc/machine/powerpc/configure: Regenerated.
        * libc/machine/powerpc/vfprintf.c[__SPE__]: Add support for
        %r and %R format specifiers which handle fixed-point data.
        * libc/machine/powerpc/vfscanf.c[__SPE__]: Ditto.
        * libc/machine/powerpc/machine/stdlib.h[__SPE__]: Add fixed-point
        function prototypes.
This commit is contained in:
Jeff Johnston 2002-08-17 05:57:20 +00:00
parent ad5527663e
commit 936b520f8e
22 changed files with 5272 additions and 2 deletions

View File

@ -1,3 +1,30 @@
2002-08-17 Jeff Johnston <jjohnstn@redhat.com>
* configure.host: Add powerpc*-*-eabispe* configuration.
* libc/machine/powerpc/atosfix16.c: New fixed-point conversion file.
* libc/machine/powerpc/atosfix32.c: Ditto.
* libc/machine/powerpc/atosfix64.c: Ditto.
* libc/machine/powerpc/atoufix16.c: Ditto.
* libc/machine/powerpc/atoufix32.c: Ditto.
* libc/machine/powerpc/atoufix64.c: Ditto.
* libc/machine/powerpc/fix64.h: Ditto.
* libc/machine/powerpc/simdldtoa.c: Ditto.
* libc/machine/powerpc/strtosfix16.c: Ditto.
* libc/machine/powerpc/strtosfix32.c: Ditto.
* libc/machine/powerpc/strtosfix64.c: Ditto.
* libc/machine/powerpc/strtoufix16.c: Ditto.
* libc/machine/powerpc/strtoufix32.c: Ditto.
* libc/machine/powerpc/strtoufix64.c: Ditto.
* libc/machine/powerpc/ufix64toa.c: Ditto.
* libc/machine/powerpc/configure.in: Add check for
powerpc*-eabispe and add fixed-point conversion functions.
* libc/machine/powerpc/configure: Regenerated.
* libc/machine/powerpc/vfprintf.c[__SPE__]: Add support for
%r and %R format specifiers which handle fixed-point data.
* libc/machine/powerpc/vfscanf.c[__SPE__]: Ditto.
* libc/machine/powerpc/machine/stdlib.h[__SPE__]: Add fixed-point
function prototypes.
2002-08-17 Jeff Johnston <jjohnstn@redhat.com>
* Makefile.am: Move cmath stuff into libc/sys/linux.

View File

@ -518,6 +518,9 @@ case "${host}" in
powerpc*-*-eabialtivec*)
newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES -DWANT_PRINTF_LONG_LONG"
;;
powerpc*-*-eabispe*)
newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES -DWANT_PRINTF_LONG_LONG"
;;
powerpc*-*-eabi* | \
powerpc*-*-elf* | \
powerpc*-*-linux* | \

View File

@ -0,0 +1,102 @@
/*
FUNCTION
<<atosfix16>>, <<atosfix32>>, <<atosfix64>>---string to signed fixed-point
INDEX
atosfix16
INDEX
atosfix32
INDEX
atosfix64
INDEX
_atosfix16_r
INDEX
_atosfix32_r
INDEX
_atosfix64_r
ANSI_SYNOPSIS
#include <stdlib.h>
__int16_t atosfix16(const char *<[s]>);
__int32_t atosfix32(const char *<[s]>);
__int64_t atosfix32(const char *<[s]>);
__int16_t _atosfix16_r(struct __reent *, const char *<[s]>);
__int32_t _atosfix32_r(struct __reent *, const char *<[s]>);
__int64_t _atosfix32_r(struct __reent *, const char *<[s]>);
TRAD_SYNOPSIS
#include <stdlib.h>
__int16_t atosfix16(<[s]>)
const char *<[s]>;
__int32_t atosfix32(<[s]>)
const char *<[s]>;
__int64_t atosfix64(<[s]>)
const char *<[s]>;
__int16_t _atosfix16_r(<reent>, <[s]>)
struct _reent *<[reent]>;
const char *<[s]>;
__int32_t _atosfix32_r(<reent>, <[s]>)
struct _reent *<[reent]>;
const char *<[s]>;
__int64_t _atosfix64_r(<reent>, <[s]>)
struct _reent *<[reent]>;
const char *<[s]>;
DESCRIPTION
<<atosfix16>> converts the initial portion of a string to a sign
+ 15-bit fraction fixed point value.
<<atosfix32>> converts the initial portion of a string to a sign
+ 31-bit fraction fixed point value.
<<atosfix64>> converts the initial portion of a string to a sign
+ 63-bit fraction fixed point value.
<<atosfix16(s)>> is implemented as <<strtosfix16(s, NULL).>>
<<atosfix32(s)>> is implemented as <<strtosfix32(s, NULL).>>
<<atosfix64(s)>> is implemented as <<strtosfix64(s, NULL).>>
The alternate functions <<_atosfix16_r>>, <<_atosfix32_r>>,
and <<_atosfix64_r>> are reentrant versions.
The extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
The functions return the converted value, if any. If no conversion was
made, <<0>> is returned. If saturation occurs, <<ERANGE>> is stored
in errno.
PORTABILITY
<<atosfix16>>, <<atosfix32>>, and <<atosfix64>> are non-standard.
No supporting OS subroutines are directly required. The
OS subroutines required by <<strtod>> are used.
*/
/*
* Jeff Johnston - 02/13/2002
*/
#include <stdlib.h>
#include <_ansi.h>
__int16_t
_DEFUN (_atosfix16_r, (reent, s),
struct _reent *reent _AND
_CONST char *s)
{
return _strtosfix16_r (reent, s, NULL);
}
#ifndef _REENT_ONLY
__int16_t
_DEFUN (atosfix16, (s),
_CONST char *s)
{
return strtosfix16 (s, NULL);
}
#endif /* !_REENT_ONLY */

View File

@ -0,0 +1,25 @@
/*
* Jeff Johnston - 02/13/2002
*/
#include <stdlib.h>
#include <_ansi.h>
__int32_t
_DEFUN (_atosfix32_r, (reent, s),
struct _reent *reent _AND
_CONST char *s)
{
return _strtosfix32_r (reent, s, NULL);
}
#ifndef _REENT_ONLY
__int32_t
_DEFUN (atosfix32, (s),
_CONST char *s)
{
return strtosfix32 (s, NULL);
}
#endif /* !_REENT_ONLY */

View File

@ -0,0 +1,25 @@
/*
* Jeff Johnston - 02/13/2002
*/
#include <stdlib.h>
#include <_ansi.h>
__int64_t
_DEFUN (_atosfix64_r, (reent, s),
struct _reent *reent _AND
_CONST char *s)
{
return _strtosfix64_r (reent, s, NULL);
}
#ifndef _REENT_ONLY
__int64_t
_DEFUN (atosfix64, (s),
_CONST char *s)
{
return strtosfix64 (s, NULL);
}
#endif /* !_REENT_ONLY */

View File

@ -0,0 +1,102 @@
/*
FUNCTION
<<atoufix16>>, <<atoufix32>>, <<atoufix64>>---string to unsigned fixed-point
INDEX
atoufix16
INDEX
atoufix32
INDEX
atoufix64
INDEX
_atoufix16_r
INDEX
_atoufix32_r
INDEX
_atoufix64_r
ANSI_SYNOPSIS
#include <stdlib.h>
__uint16_t atoufix16(const char *<[s]>);
__uint32_t atoufix32(const char *<[s]>);
__uint64_t atoufix32(const char *<[s]>);
__uint16_t _atoufix16_r(struct __reent *, const char *<[s]>);
__uint32_t _atoufix32_r(struct __reent *, const char *<[s]>);
__uint64_t _atoufix32_r(struct __reent *, const char *<[s]>);
TRAD_SYNOPSIS
#include <stdlib.h>
__uint16_t atoufix16(<[s]>)
const char *<[s]>;
__uint32_t atoufix32(<[s]>)
const char *<[s]>;
__uint64_t atoufix64(<[s]>)
const char *<[s]>;
__uint16_t _atoufix16_r(<reent>, <[s]>)
struct _reent *<[reent]>;
const char *<[s]>;
__uint32_t _atoufix32_r(<reent>, <[s]>)
struct _reent *<[reent]>;
const char *<[s]>;
__uint64_t _atoufix64_r(<reent>, <[s]>)
struct _reent *<[reent]>;
const char *<[s]>;
DESCRIPTION
<<atoufix16>> converts the initial portion of a string to a
16-bit fraction unsigned fixed point value.
<<atoufix32>> converts the initial portion of a string to a
32-bit fraction unsigned fixed point value.
<<atoufix64>> converts the initial portion of a string to a
64-bit fraction unsigned fixed point value.
<<atoufix16(s)>> is implemented as <<strtoufix16(s, NULL).>>
<<atoufix32(s)>> is implemented as <<strtoufix32(s, NULL).>>
<<atoufix64(s)>> is implemented as <<strtoufix64(s, NULL).>>
The alternate functions <<_atoufix16_r>>, <<_atoufix32_r>>,
and <<_atoufix64_r>> are reentrant versions.
The extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
The functions return the converted value, if any. If no conversion was
made, <<0>> is returned. If saturation occurs, <<ERANGE>> is stored
in errno.
PORTABILITY
<<atoufix16>>, <<atoufix32>>, and <<atoufix64>> are non-standard.
No supporting OS subroutines are directly required. The
OS subroutines required by <<strtod>> are used.
*/
/*
* Jeff Johnston - 02/13/2002
*/
#include <stdlib.h>
#include <_ansi.h>
__uint16_t
_DEFUN (_atoufix16_r, (reent, s),
struct _reent *reent _AND
_CONST char *s)
{
return _strtoufix16_r (reent, s, NULL);
}
#ifndef _REENT_ONLY
__uint16_t
_DEFUN (atoufix16, (s),
_CONST char *s)
{
return strtoufix16 (s, NULL);
}
#endif /* !_REENT_ONLY */

View File

@ -0,0 +1,25 @@
/*
* Jeff Johnston - 02/13/2002
*/
#include <stdlib.h>
#include <_ansi.h>
__uint32_t
_DEFUN (_atoufix32_r, (reent, s),
struct _reent *reent _AND
_CONST char *s)
{
return _strtoufix32_r (reent, s, NULL);
}
#ifndef _REENT_ONLY
__uint32_t
_DEFUN (atoufix32, (s),
_CONST char *s)
{
return strtoufix32 (s, NULL);
}
#endif /* !_REENT_ONLY */

View File

@ -0,0 +1,25 @@
/*
* Jeff Johnston - 02/13/2002
*/
#include <stdlib.h>
#include <_ansi.h>
__uint64_t
_DEFUN (_atoufix64_r, (reent, s),
struct _reent *reent _AND
_CONST char *s)
{
return _strtoufix64_r (reent, s, NULL);
}
#ifndef _REENT_ONLY
__uint64_t
_DEFUN (atoufix64, (s),
_CONST char *s)
{
return strtoufix64 (s, NULL);
}
#endif /* !_REENT_ONLY */

View File

@ -1494,6 +1494,10 @@ case $host in
extra_objs="vfprintf.o vfscanf.o vec_malloc.o vec_calloc.o vec_free.o vec_realloc.o vec_reallocr.o vec_callocr.o"
extra_sources="vfprintf.c vfscanf.c vec_malloc.c vec_calloc.c vec_free.c vec_realloc.c vec_mallocr.c"
;;
powerpc*-*spe*)
extra_objs="atosfix16.o atosfix32.o atosfix64.o atoufix16.o atoufix32.o atoufix64.o simdldtoa.o strtosfix16.o strtosfix32.o strtosfix64.o strtoufix16.o strtoufix32.o strtoufix64.o ufix64toa.o vfprintf.o vfscanf.o"
extra_sources="atosfix16.c atosfix32.c atosfix64.c atoufix16.c atoufix32.c atoufix64.c simdldtoa.c strtosfix16.c strtosfix32.c strtosfix64.c strtoufix16.c strtoufix32.c strtoufix64.c ufix64toa.c vfprintf.c vfscanf.c"
;;
esac

View File

@ -16,6 +16,10 @@ case $host in
extra_objs="vfprintf.o vfscanf.o vec_malloc.o vec_calloc.o vec_free.o vec_realloc.o vec_reallocr.o vec_callocr.o"
extra_sources="vfprintf.c vfscanf.c vec_malloc.c vec_calloc.c vec_free.c vec_realloc.c vec_mallocr.c"
;;
powerpc*-*spe*)
extra_objs="atosfix16.o atosfix32.o atosfix64.o atoufix16.o atoufix32.o atoufix64.o simdldtoa.o strtosfix16.o strtosfix32.o strtosfix64.o strtoufix16.o strtoufix32.o strtoufix64.o ufix64toa.o vfprintf.o vfscanf.o"
extra_sources="atosfix16.c atosfix32.c atosfix64.c atoufix16.c atoufix32.c atoufix64.c simdldtoa.c strtosfix16.c strtosfix32.c strtosfix64.c strtoufix16.c strtoufix32.c strtoufix64.c ufix64toa.c vfprintf.c vfscanf.c"
;;
esac
AC_SUBST(extra_objs)
AC_SUBST(extra_sources)

View File

@ -0,0 +1,80 @@
#ifndef _FIX64_H_
#define _FIX64_H_
#include <ieeefp.h>
#include <math.h>
#include <float.h>
#include <errno.h>
#include <sys/config.h>
#ifdef __IEEE_LITTLE_ENDIAN
#define IEEE_8087
#endif
#ifdef __IEEE_BIG_ENDIAN
#define IEEE_MC68k
#endif
#ifdef __Z8000__
#define Just_16
#endif
#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
#endif
union long_double_union
{
long double ld;
__uint32_t i[4];
};
typedef union long_double_union LONG_DOUBLE_UNION;
extern void _simdstrtold (char *, char **, LONG_DOUBLE_UNION *);
extern int _simdldchk (LONG_DOUBLE_UNION *);
#define SIMD_LDBL_MANT_DIG 113
#ifdef IEEE_8087
# define word0(x) (x.i[3])
# define word1(x) (x.i[2])
# define word2(x) (x.i[1])
# define word3(x) (x.i[0])
#else /* !IEEE_8087 */
# define word0(x) (x.i[0])
# define word1(x) (x.i[1])
# define word2(x) (x.i[2])
# define word3(x) (x.i[3])
#endif /* !IEEE_8087 */
#undef Exp_shift
#define Exp_shift 16
#undef Exp_mask
#define Exp_mask ((__uint32_t)0x7fff0000L)
#undef Exp_msk1
#define Exp_msk1 ((__uint32_t)0x00010000L)
#undef Bias
#define Bias 16383
#undef Ebits
#define Ebits 15
#undef Sign_bit
#define Sign_bit ((__uint32_t)0x80000000L)
#define init(x) {}
union fix64_union
{
__uint64_t ll;
__uint32_t j[2];
};
#ifdef __LITTLE_ENDIAN__
# define hiword(y) (y.j[1])
# define loword(y) (y.j[0])
#else /* __BIG_ENDIAN__ */
# define hiword(y) (y.j[0])
# define loword(y) (y.j[1])
#endif /* __BIG_ENDIAN__ */
#endif /* _FIX64_H_ */

View File

@ -16,6 +16,44 @@ _PTR _EXFUN(_vec_realloc_r,(struct _reent *, _PTR __r, size_t __size));
# endif /* __ALTIVEC__ */
# if defined(__SPE__)
__int16_t _EXFUN(atosfix16,(const char *__str));
__int16_t _EXFUN(_atosfix16_r,(struct _reent *, const char *__str));
__int32_t _EXFUN(atosfix32,(const char *__str));
__int32_t _EXFUN(_atosfix32_r,(struct _reent *, const char *__str));
__int64_t _EXFUN(atosfix64,(const char *__str));
__int64_t _EXFUN(_atosfix64_r,(struct _reent *, const char *__str));
__uint16_t _EXFUN(atoufix16,(const char *__str));
__uint16_t _EXFUN(_atoufix16_r,(struct _reent *, const char *__str));
__uint32_t _EXFUN(atoufix32,(const char *__str));
__uint32_t _EXFUN(_atoufix32_r,(struct _reent *, const char *__str));
__uint64_t _EXFUN(atoufix64,(const char *__str));
__uint64_t _EXFUN(_atoufix64_r,(struct _reent *, const char *__str));
__int16_t _EXFUN(strtosfix16,(const char *__str, char **__endptr));
__int16_t _EXFUN(_strtosfix16_r,(struct _reent *, const char *__str,
char **__endptr));
__int32_t _EXFUN(strtosfix32,(const char *__str, char **__endptr));
__int32_t _EXFUN(_strtosfix32_r,(struct _reent *, const char *__str,
char **__endptr));
__int64_t _EXFUN(strtosfix64,(const char *__str, char **__endptr));
__int64_t _EXFUN(_strtosfix64_r,(struct _reent *, const char *__str,
char **__endptr));
__uint16_t _EXFUN(strtoufix16,(const char *__str, char **__endptr));
__uint16_t _EXFUN(_strtoufix16_r,(struct _reent *, const char *__str,
char **__endptr));
__uint32_t _EXFUN(strtoufix32,(const char *__str, char **__endptr));
__uint32_t _EXFUN(_strtoufix32_r,(struct _reent *, const char *__str,
char **__endptr));
__uint64_t _EXFUN(strtoufix64,(const char *__str, char **__endptr));
__uint64_t _EXFUN(_strtoufix64_r,(struct _reent *, const char *__str,
char **__endptr));
# endif /* __SPE__ */
#endif /* !__STRICT_ANSI__ */

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -0,0 +1,100 @@
#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 + 31-bits) value.
*
* Ignores `locale' stuff.
*/
__int32_t
_DEFUN (_strtosfix32_r, (rptr, nptr, endptr),
struct _reent *rptr _AND
_CONST char *nptr _AND
char **endptr)
{
union double_union dbl;
int exp, negexp, sign;
unsigned long tmp, tmp2;
long result = 0;
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 LONG_MIN;
return LONG_MAX;
}
/* check for normal saturation */
if (dbl.d >= 1.0)
{
rptr->_errno = ERANGE;
return LONG_MAX;
}
else if (dbl.d < -1.0)
{
rptr->_errno = ERANGE;
return LONG_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 > 31)
return 0;
word0(dbl) &= ~(Exp_mask | Sign_bit);
/* add in implicit normalized bit */
word0(dbl) |= Exp_msk1;
/* shift so result is contained in single word */
tmp = word0(dbl) << Ebits;
tmp |= ((unsigned long)word1(dbl) >> (32 - Ebits));
if (negexp != 0)
{
/* perform rounding */
tmp2 = tmp + (1 << (negexp - 1));
result = (long)(tmp2 >> negexp);
/* check if rounding caused carry bit which must be added into result */
if (tmp2 < tmp)
result |= (1 << (32 - negexp));
/* check if positive saturation has occurred because of rounding */
if (!sign && result < 0)
{
rptr->_errno = ERANGE;
return LONG_MAX;
}
}
else
{
/* we have -1.0, no rounding necessary */
return LONG_MIN;
}
return sign ? -result : result;
}
#ifndef _REENT_ONLY
__int32_t
_DEFUN (strtosfix32, (s, ptr, base),
_CONST char *s _AND
char **ptr)
{
return _strtosfix32_r (_REENT, s, ptr);
}
#endif

View File

@ -0,0 +1,113 @@
#include <_ansi.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include <reent.h>
#include "fix64.h"
/*
* Convert a string to a fixed-point (sign + 63-bits) value.
*
* Ignores `locale' stuff.
*/
__int64_t
_DEFUN (_strtosfix64_r, (rptr, nptr, endptr),
struct _reent *rptr _AND
_CONST char *nptr _AND
char **endptr)
{
union long_double_union ldbl;
int exp, negexp, sign, ld_type;
__uint64_t tmp, tmp2;
__int64_t result = 0;
init(ldbl);
_simdstrtold ((char *)nptr, endptr, &ldbl);
/* treat NAN as domain error, +/- infinity as saturation */
ld_type = _simdldcheck (&ldbl.ld);
if (ld_type != 0)
{
if (ld_type == 1)
{
rptr->_errno = EDOM;
return 0;
}
rptr->_errno = ERANGE;
if (word0(ldbl) & Sign_bit)
return LONG_LONG_MIN;
return LONG_LONG_MAX;
}
/* strip off sign and exponent */
sign = word0(ldbl) & Sign_bit;
exp = ((word0(ldbl) & Exp_mask) >> Exp_shift) - Bias;
negexp = -exp;
if (negexp > 63)
return 0;
word0(ldbl) &= ~(Exp_mask | Sign_bit);
/* add in implicit normalized bit */
word0(ldbl) |= Exp_msk1;
/* shift so result is contained in single word */
tmp = word0(ldbl) << Ebits;
tmp |= ((unsigned long)word1(ldbl) >> (32 - Ebits));
tmp <<= 32;
if (Ebits < 32)
tmp |= ((unsigned long)word1(ldbl) << Ebits);
tmp |= ((unsigned long)word2(ldbl) >> (32 - Ebits));
/* check for saturation */
if (sign)
{
if (exp > 0 || (exp == 0 && tmp != 0x8000000000000000LL))
{
rptr->_errno = ERANGE;
return LONG_LONG_MIN;
}
}
else
{
if (exp >= 0)
{
rptr->_errno = ERANGE;
return LONG_LONG_MAX;
}
}
/* otherwise we have normal number in range */
if (negexp != 0)
{
/* perform rounding */
tmp2 = tmp + (1 << (negexp - 1));
result = (long long)(tmp2 >> negexp);
/* check if rounding caused carry bit which must be added into result */
if (tmp2 < tmp)
result |= (1 << (64 - negexp));
/* check if positive saturation has occurred because of rounding */
if (!sign && result < 0)
{
rptr->_errno = ERANGE;
return LONG_LONG_MAX;
}
}
else
{
/* we have -1.0, no rounding necessary */
return LONG_LONG_MIN;
}
return sign ? -result : result;
}
#ifndef _REENT_ONLY
__int64_t
_DEFUN (strtosfix64, (s, ptr, base),
_CONST char *s _AND
char **ptr)
{
return _strtosfix64_r (_REENT, s, ptr);
}
#endif

View File

@ -0,0 +1,197 @@
/*
FUNCTION
<<strtoufix16>>, <<strtoufix32>>, <<strtoufix64>>---string to signed fixed point
INDEX
strtoufix16
INDEX
strtoufix32
INDEX
strtoufix64
INDEX
_strtoufix16_r
INDEX
_strtoufix32_r
INDEX
_strtoufix64_r
ANSI_SYNOPSIS
#include <stdlib.h>
__uint16_t strtoufix16 (const char *<[s]>, char **<[ptr]>);
__uint32_t strtoufix32 (const char *<[s]>, char **<[ptr]>);
__uint64_t strtoufix64 (const char *<[s]>, char **<[ptr]>);
__uint16_t _strtoufix16_r (void *<[reent]>,
const char *<[s]>, char **<[ptr]>);
__uint32_t _strtoufix32_r (void *<[reent]>,
const char *<[s]>, char **<[ptr]>);
__uint64_t _strtoufix64_r (void *<[reent]>,
const char *<[s]>, char **<[ptr]>);
TRAD_SYNOPSIS
#include <stdlib.h>
__uint16_t strtoufix16 (<[s]>, <[ptr]>)
char *<[s]>;
char **<[ptr]>;
__uint32_t strtoufix32 (<[s]>, <[ptr]>)
char *<[s]>;
char **<[ptr]>;
__uint64_t strtoufix64 (<[s]>, <[ptr]>)
char *<[s]>;
char **<[ptr]>;
__uint16_t _strtoufix16_r (<[reent]>, <[s]>, <[ptr]>)
char *<[reent]>;
char *<[s]>;
char **<[ptr]>;
__uint32_t _strtoufix32_r (<[reent]>, <[s]>, <[ptr]>)
char *<[reent]>;
char *<[s]>;
char **<[ptr]>;
__uint64_t _strtoufix64_r (<[reent]>, <[s]>, <[ptr]>)
char *<[reent]>;
char *<[s]>;
char **<[ptr]>;
DESCRIPTION
The function <<strtoufix16>> converts the string <<*<[s]>>> to
a fixed-point 16-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]>.
<<strtoufix32>> is identical to <<strtoufix16>> except that it
converts to fixed-point 32-bit fraction representation.
<<strtoufix64>> is also similar, except that it converts
to fixed-point 64-bit fraction.
The alternate functions <<_strtoufix16_r>>, <<_strtoufix32_r>>,
and <<_strtoufix64_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 unsigned 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 0, then the output is saturated to 0
and <<ERANGE>> is stored in errno. Otherwise, the converted value is returned in the
specified fixed-point format.
PORTABILITY
<<strtoufix16>>, <<strtoufix32>>, and <<strtoufix64>> 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 16-bit value.
*
* Ignores `locale' stuff.
*/
__uint16_t
_DEFUN (_strtoufix16_r, (rptr, nptr, endptr),
struct _reent *rptr _AND
_CONST char *nptr _AND
char **endptr)
{
union double_union dbl;
unsigned long tmp, tmp2, result;
int exp, negexp;
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 0;
return USHRT_MAX;
}
/* check for normal saturation */
if (dbl.d >= 1.0)
{
rptr->_errno = ERANGE;
return USHRT_MAX;
}
else if (dbl.d < 0)
{
rptr->_errno = ERANGE;
return 0;
}
/* otherwise we have normal postive number in range */
/* strip off exponent */
exp = ((word0(dbl) & Exp_mask) >> Exp_shift) - Bias;
negexp = -exp;
if (negexp > 16)
return 0;
/* add in implicit normalized bit */
tmp = word0(dbl) | Exp_msk1;
/* remove exponent and sign */
tmp <<= Ebits;
/* perform rounding */
tmp2 = tmp + (1 << (negexp + 14));
result = tmp2 >> (negexp + 15);
/* if rounding causes carry, must add carry bit in */
if (tmp2 < tmp)
{
if (negexp == 0)
{
/* we have overflow which means saturation */
rptr->_errno = ERANGE;
return USHRT_MAX;
}
result |= (1 << (16 - negexp));
}
return (__uint16_t)result;
}
#ifndef _REENT_ONLY
__uint16_t
_DEFUN (strtoufix16, (s, ptr, base),
_CONST char *s _AND
char **ptr)
{
return _strtoufix16_r (_REENT, s, ptr);
}
#endif

View File

@ -0,0 +1,97 @@
#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 32-bit value.
*
* Ignores `locale' stuff.
*/
__uint32_t
_DEFUN (_strtoufix32_r, (rptr, nptr, endptr),
struct _reent *rptr _AND
_CONST char *nptr _AND
char **endptr)
{
union double_union dbl;
int exp, negexp, sign;
__uint32_t tmp, tmp2, result = 0;
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 0;
return ULONG_MAX;
}
/* check for normal saturation */
if (dbl.d >= 1.0)
{
rptr->_errno = ERANGE;
return ULONG_MAX;
}
else if (dbl.d < 0)
{
rptr->_errno = ERANGE;
return 0;
}
/* otherwise we have normal positive number in range */
/* strip off exponent */
exp = ((word0(dbl) & Exp_mask) >> Exp_shift) - Bias;
negexp = -exp;
if (negexp > 32)
return 0;
word0(dbl) &= ~(Exp_mask | Sign_bit);
/* add in implicit normalized bit */
word0(dbl) |= Exp_msk1;
/* shift so result is contained left-justified in word */
tmp = word0(dbl) << Ebits;
tmp |= ((unsigned long)word1(dbl) >> (32 - Ebits));
/* perform rounding */
if (negexp > 1)
{
tmp2 = tmp + (1 << (negexp - 2));
result = (tmp2 >> (negexp - 1));
/* if rounding causes carry, add carry bit in */
if (tmp2 < tmp)
result += 1 << (32 - negexp);
}
else
{
result = tmp + ((word1(dbl) & (1 << (32 - Ebits - 1))) != 0);
/* if rounding causes carry, then saturation has occurred */
if (result < tmp)
{
rptr->_errno = ERANGE;
return ULONG_MAX;
}
}
return result;
}
#ifndef _REENT_ONLY
__uint32_t
_DEFUN (strtoufix32, (s, ptr, base),
_CONST char *s _AND
char **ptr)
{
return _strtoufix32_r (_REENT, s, ptr);
}
#endif

View File

@ -0,0 +1,115 @@
#include <_ansi.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include <reent.h>
#include "fix64.h"
/*
* Convert a string to a fixed-point 64-bit unsigned value.
*
* Ignores `locale' stuff.
*/
__uint64_t
_DEFUN (_strtoufix64_r, (rptr, nptr, endptr),
struct _reent *rptr _AND
_CONST char *nptr _AND
char **endptr)
{
union long_double_union ldbl;
int exp, sign, negexp, ld_type;
__uint64_t tmp, tmp2, result = 0;
init(ldbl);
_simdstrtold ((char *)nptr, endptr, &ldbl);
/* treat NAN as domain error, +/- infinity as saturation */
ld_type = _simdldcheck (&ldbl.ld);
if (ld_type != 0)
{
if (ld_type == 1)
{
rptr->_errno = EDOM;
return 0;
}
rptr->_errno = ERANGE;
if (word0(ldbl) & Sign_bit)
return 0;
return ULONG_LONG_MAX;
}
/* strip off sign and exponent */
sign = word0(ldbl) & Sign_bit;
exp = ((word0(ldbl) & Exp_mask) >> Exp_shift) - Bias;
negexp = -exp;
if (negexp > 63)
return 0;
word0(ldbl) &= ~(Exp_mask | Sign_bit);
/* add in implicit normalized bit */
word0(ldbl) |= Exp_msk1;
/* shift so result is contained in single word */
tmp = word0(ldbl) << Ebits;
tmp |= ((unsigned long)word1(ldbl) >> (32 - Ebits));
tmp <<= 32;
if (Ebits < 32)
tmp |= ((unsigned long)word1(ldbl) << Ebits);
tmp |= ((unsigned long)word2(ldbl) >> (32 - Ebits));
/* check for saturation */
if (sign)
{
rptr->_errno = ERANGE;
return 0;
}
else
{
if (exp > 0 || (exp == 0 && tmp >= 0x8000000000000000LL))
{
rptr->_errno = ERANGE;
return ULONG_LONG_MAX;
}
}
/* otherwise we have normal number in range */
if (negexp > 1)
{
tmp2 = tmp + (1 << (negexp - 2));
result = (tmp2 >> (negexp - 1));
/* if rounding causes carry, add carry bit in */
if (tmp2 < tmp)
result += 1 << (64 - negexp);
}
else
{
if (Ebits < 32)
{
result = tmp + ((word2(ldbl) & (1 << (64 - Ebits - 1))) != 0);
/* if rounding causes carry, then saturation has occurred */
if (result < tmp)
{
rptr->_errno = ERANGE;
return ULONG_LONG_MAX;
}
}
else
result = tmp;
}
return result;
}
#ifndef _REENT_ONLY
__uint64_t
_DEFUN (strtoufix64, (s, ptr, base),
_CONST char *s _AND
char **ptr)
{
return _strtoufix64_r (_REENT, s, ptr);
}
#endif

View File

@ -0,0 +1,88 @@
/* _ufix64toa_r: convert unsigned 64-bit fixed point to ASCII string.
*
* This routine converts an unsigned fixed-point number to long double format and
* then calls _ldtoa_r to do the conversion.
*
* Written by Jeff Johnston.
*/
#include <_ansi.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include <reent.h>
#include "fix64.h"
extern char *_simdldtoa_r _PARAMS((struct _reent *, LONG_DOUBLE_UNION *, int,
int, int *, int *, char **));
/*
* Convert an unsigned fixed-point 64-bit value to string.
*
* Ignores `locale' stuff.
*/
char *
_DEFUN (_ufix64toa_r, (rptr, value, mode, ndigits, decpt, sign, rve),
struct _reent *rptr _AND
__uint64_t value _AND
int mode _AND
int ndigits _AND
int *decpt _AND
int *sign _AND
char **rve)
{
union long_double_union ldbl;
union fix64_union fix64;
unsigned long tmp;
int exp, negexp;
/* if input is 0, no additional work is needed */
if (value == 0)
{
ldbl.i[0] = ldbl.i[1] = ldbl.i[2] = ldbl.i[3] = 0;
}
else /* otherwise, we calculate long double equivalent of value */
{
/* find exponent by locating most-significant one-bit */
fix64.ll = value;
negexp = 1;
if (hiword(fix64) == 0)
{
tmp = loword(fix64);
negexp = 33;
}
else
{
tmp = hiword(fix64);
negexp = 1;
}
while (negexp < 65)
{
if (tmp & 0x80000000)
break;
++negexp;
tmp <<= 1;
}
/* shift input appropriately */
fix64.ll = value << (negexp - 1 + (Exp_msk1 != 0));
/* build long double */
exp = -negexp + Bias;
word0(ldbl) = (exp << Exp_shift);
word1(ldbl) = hiword(fix64) << (32-Ebits);
word2(ldbl) = loword(fix64) << (32-Ebits);
word3(ldbl) = 0;
if (Ebits < 32)
{
word0(ldbl) |= hiword(fix64) >> Ebits;
word1(ldbl) |= loword(fix64) >> Ebits;
}
}
/* convert long double to character */
return _simdldtoa_r (rptr, &ldbl, mode, ndigits, decpt, sign, rve);
}

View File

@ -166,6 +166,8 @@ static char *rcsid = "$Id$";
#include <stdlib.h>
#include <string.h>
#include <reent.h>
#include <wchar.h>
#include <string.h>
#ifdef __ALTIVEC__
#include <altivec.h>
#endif
@ -275,6 +277,10 @@ extern int _ldcheck _PARAMS((_LONG_DOUBLE *));
static int exponent _PARAMS((char *, int, int));
#ifdef __SPE__
static char *cvt_ufix64 _PARAMS((struct _reent *, unsigned long long, int, int *, int *));
#endif /* __SPE__ */
#else /* no FLOATING_POINT */
#define BUF 40
@ -308,6 +314,7 @@ static int exponent _PARAMS((char *, int, int));
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
#define FPT 0x100 /* Floating point number */
#define VECTOR 0x200 /* vector */
#define FIXEDPOINT 0x400 /* fixed-point */
int
_DEFUN (VFPRINTF, (fp, fmt0, ap),
@ -382,7 +389,7 @@ _DEFUN (_VFPRINTF_R, (data, fp, fmt0, ap),
int vec_print_count; /* number of vector chunks remaining */
vec_16_byte_union vec_tmp;
#endif /* __ALTIVEC__ */
int state = 0; /* mbtowc calls from library must not change state */
mbstate_t state; /* mbtowc calls from library must not change state */
/*
* Choose PADSIZE to trade efficiency vs. size. If larger printf
@ -480,6 +487,16 @@ _DEFUN (_VFPRINTF_R, (data, fp, fmt0, ap),
flags&LONGINT ? GET_ULONG(ap) : \
flags&SHORTINT ? (u_long)GET_USHORT(ap) : \
(u_long)GET_UINT(ap))
#ifdef __SPE__
#define SFPARG() \
(flags&LONGINT ? va_arg(ap, quad_t) : \
flags&SHORTINT ? (long)GET_SHORT(ap) : \
(long)va_arg(ap, int))
#define UFPARG() \
(flags&LONGINT ? va_arg(ap, u_quad_t) : \
flags&SHORTINT ? (u_long)GET_USHORT(ap) : \
(u_long)va_arg(ap, u_int))
#endif /* __SPE__ */
#else
#define SARG() \
(flags&LONGINT ? GET_LONG(ap) : \
@ -489,8 +506,20 @@ _DEFUN (_VFPRINTF_R, (data, fp, fmt0, ap),
(flags&LONGINT ? GET_ULONG(ap) : \
flags&SHORTINT ? (u_long)GET_USHORT(ap) : \
(u_long)GET_UINT(ap))
#ifdef __SPE__
#define SFPARG() \
(flags&LONGINT ? (va_arg(ap, long) << 32) : \
flags&SHORTINT ? (long)GET_SHORT(ap) : \
(long)va_arg(ap, int))
#define UFPARG() \
(flags&LONGINT ? (va_arg(ap, u_long) <<32) : \
flags&SHORTINT ? (u_long)GET_USHORT(ap) : \
(u_long)va_arg(ap, u_int))
#endif /* __SPE__ */
#endif
memset (&state, '\0', sizeof (state));
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
if (cantwrite(fp))
return (EOF);
@ -863,6 +892,51 @@ reswitch: switch (ch) {
}
break;
#endif /* FLOATING_POINT */
#ifdef __SPE__
case 'r':
flags |= FIXEDPOINT;
_uquad = SFPARG();
if ((quad_t)_uquad < 0)
{
sign = '-';
_uquad = -(quad_t)_uquad;
}
if (flags & SHORTINT)
_uquad <<= 49;
else if (flags & LONGINT)
_uquad <<= 1;
else
_uquad <<= 33;
if (_uquad == 0 && sign)
{
/* we have -1.0 which has to be handled special */
cp = "100000";
expt = 1;
ndig = 6;
break;
}
goto fixed_nosign;
case 'R':
flags |= FIXEDPOINT;
_uquad = UFPARG();
if (flags & SHORTINT)
_uquad <<= 48;
else if (!(flags & LONGINT))
_uquad <<= 32;
fixed_nosign:
if (prec == -1)
prec = DEFPREC;
cp = cvt_ufix64 (data, _uquad, prec, &expt, &ndig);
/* act like %f of format "0.X" */
size = prec + 2;
break;
#endif /* __SPE__ */
case 'n':
#ifdef __ALTIVEC__
if (flags & VECTOR)
@ -1107,6 +1181,35 @@ number: if ((dprec = prec) >= 0)
/* the string or number proper */
#ifdef FLOATING_POINT
if ((flags & FPT) == 0) {
#ifdef __SPE__
if (flags & FIXEDPOINT) {
if (_uquad == 0 && !sign) {
/* kludge for __dtoa irregularity */
PRINT("0", 1);
if (expt < ndig || (flags & ALT) != 0) {
PRINT(decimal_point, 1);
PAD(ndig - 1, zeroes);
}
} else if (expt <= 0) {
PRINT("0", 1);
if(expt || ndig) {
PRINT(decimal_point, 1);
PAD(-expt, zeroes);
PRINT(cp, ndig);
}
} else if (expt >= ndig) {
PRINT(cp, ndig);
PAD(expt - ndig, zeroes);
if (flags & ALT)
PRINT(".", 1);
} else {
PRINT(cp, expt);
cp += expt;
PRINT(".", 1);
PRINT(cp, ndig-expt);
}
} else
#endif /* __SPE__ */
PRINT(cp, size);
} else { /* glue together f_p fragments */
if (ch >= 'f') { /* 'f' or 'g' */
@ -1297,3 +1400,31 @@ exponent(p0, exp, fmtch)
}
#endif /* FLOATING_POINT */
#ifdef __SPE__
extern char *_ufix64toa_r _PARAMS((struct _reent *, unsigned long long, int,
int, int *, int *, char **));
static char *
cvt_ufix64 (data, value, ndigits, decpt, length)
struct _reent *data;
unsigned long long value;
int ndigits, *decpt, *length;
{
int dsgn;
char *digits, *bp, *rve;
/* treat the same as %f format and use mode=3 */
digits = _ufix64toa_r (data, value, 3, ndigits, decpt, &dsgn, &rve);
/* print trailing zeroes */
bp = digits + ndigits;
if (*digits == '0' && value)
*decpt = -ndigits + 1;
bp += *decpt;
if (value == 0) /* kludge for __dtoa irregularity */
rve = bp;
while (rve < bp)
*rve++ = '0';
*length = rve - digits;
return (digits);
}
#endif /* __SPE__ */

View File

@ -107,6 +107,8 @@ Supporting OS subroutines required:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <wchar.h>
#include <string.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
@ -130,6 +132,11 @@ Supporting OS subroutines required:
extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
#endif
#ifdef __SPE__
extern __int64_t _strtosfix64_r _PARAMS((struct _reent *, char *s, char **sptr));
extern __uint64_t _strtoufix64_r _PARAMS((struct _reent *, char *s, char **sptr));
#endif
#define _NO_LONGLONG
#if defined WANT_PRINTF_LONG_LONG && defined __GNUC__
# undef _NO_LONGLONG
@ -171,6 +178,8 @@ extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
#define NZDIGITS 0x200 /* no zero digits detected */
#define VECTOR 0x400 /* v: vector */
#define FIXEDPOINT 0x800 /* r/R: fixed-point */
#define SIGNED 0x1000 /* r: signed fixed-point */
/*
* Conversion types.
@ -275,7 +284,7 @@ __svfscanf_r (rptr, fp, fmt0, ap)
vec_union vec_buf;
char *lptr; /* literal pointer */
#ifdef MB_CAPABLE
int state = 0; /* value to keep track of multibyte state */
mbstate_t state; /* value to keep track of multibyte state */
#endif
char *ch_dest;
@ -302,6 +311,7 @@ __svfscanf_r (rptr, fp, fmt0, ap)
#ifndef MB_CAPABLE
wc = *fmt;
#else
memset (&state, '\0', sizeof (state));
nbytes = _mbtowc_r (rptr, &wc, fmt, MB_CUR_MAX, &state);
#endif
fmt += nbytes;
@ -467,6 +477,16 @@ __svfscanf_r (rptr, fp, fmt0, ap)
vec_read_count = 4;
break;
# ifdef __SPE__
/* treat fixed-point like %f floating point */
case 'r':
flags |= SIGNED;
/* fallthrough */
case 'R':
flags |= FIXEDPOINT;
type = CT_FLOAT;
break;
# endif
#endif
case 's':
@ -1138,6 +1158,34 @@ __svfscanf_r (rptr, fp, fmt0, ap)
exp_start = buf + sizeof (buf) - MAX_LONG_LEN - 1;
sprintf (exp_start, "e%ld", new_exp);
}
#ifdef __SPE__
if (flags & FIXEDPOINT)
{
__uint64_t ufix64;
if (flags & SIGNED)
ufix64 = (__uint64_t)_strtosfix64_r (rptr, buf, NULL);
else
ufix64 = _strtoufix64_r (rptr, buf, NULL);
if (flags & SHORT)
{
__uint16_t *sp = va_arg (ap, __uint16_t *);
*sp = (__uint16_t)(ufix64 >> 48);
}
else if (flags & LONG)
{
__uint64_t *llp = va_arg (ap, __uint64_t *);
*llp = ufix64;
}
else
{
__uint32_t *lp = va_arg (ap, __uint32_t *);
*lp = (__uint32_t)(ufix64 >> 32);
}
nassigned++;
break;
}
#endif /* __SPE__ */
#ifdef _NO_LONGDBL
res = _strtod_r (rptr, buf, NULL);
#else /* !_NO_LONGDBL */