From 5520ae71f123a813c907191105b652401594d319 Mon Sep 17 00:00:00 2001 From: joseph Date: Thu, 25 Jan 2007 02:21:06 +0000 Subject: * sysdeps/powerpc/powerpc32/e500/fpu/tst-spepim.c: New. * sysdeps/powerpc/powerpc32/e500/fpu/Makefile: Enable new test. * sysdeps/powerpc/powerpc32/e500/fpu/strtofix.c (STRTOFIX): Check for invalid numbers starting "0x" with no following digits. Correct exponent normalization for hex numbers. Correct handling of low digits in hex numbers. git-svn-id: svn://svn.eglibc.org/trunk@1277 7b3dc134-2b1b-0410-93df-9e9f96275f8d --- ports/sysdeps/powerpc/powerpc32/e500/fpu/Makefile | 6 + .../sysdeps/powerpc/powerpc32/e500/fpu/strtofix.c | 10 +- .../powerpc/powerpc32/e500/fpu/tst-spepim.c | 494 +++++++++++++++++++++ 3 files changed, 508 insertions(+), 2 deletions(-) create mode 100644 ports/sysdeps/powerpc/powerpc32/e500/fpu/tst-spepim.c (limited to 'ports/sysdeps/powerpc') diff --git a/ports/sysdeps/powerpc/powerpc32/e500/fpu/Makefile b/ports/sysdeps/powerpc/powerpc32/e500/fpu/Makefile index 80422f202..3e7c9e92f 100644 --- a/ports/sysdeps/powerpc/powerpc32/e500/fpu/Makefile +++ b/ports/sysdeps/powerpc/powerpc32/e500/fpu/Makefile @@ -2,4 +2,10 @@ ifeq ($(subdir),stdlib) spepim_routines = atosfix16 atosfix32 atosfix64 atoufix16 atoufix32 atoufix64 \ strtosfix16 strtosfix32 strtosfix64 strtoufix16 strtoufix32 strtoufix64 sysdep_routines += $(spepim_routines) +tests += tst-spepim +ifeq ($(build-shared),yes) +$(objpfx)tst-spepim: $(common-objpfx)math/libm.so$(libm.so-version) +else +$(objpfx)tst-spepim: $(common-objpfx)math/libm.a +endif endif diff --git a/ports/sysdeps/powerpc/powerpc32/e500/fpu/strtofix.c b/ports/sysdeps/powerpc/powerpc32/e500/fpu/strtofix.c index 6181fe12f..653006835 100644 --- a/ports/sysdeps/powerpc/powerpc32/e500/fpu/strtofix.c +++ b/ports/sysdeps/powerpc/powerpc32/e500/fpu/strtofix.c @@ -409,6 +409,12 @@ STRTOFIX (const char *nptr, char **endptr) } } + /* For numbers like "0x." with no hex digits, only the "0" is valid. */ + if (base == 16 + && startp == start_of_digits + && dig_no == 0) + RETURN (0, start_of_digits - 1); + /* Remember start of exponent (if any). */ expp = cp; @@ -562,7 +568,7 @@ STRTOFIX (const char *nptr, char **endptr) /* Normalize the exponent so that all digits can be considered to start just after the point. */ - exponent += int_no; + exponent += base == 16 ? 4 * int_no : int_no; if (exponent > (base == 16 ? 4 : 1)) { @@ -647,7 +653,7 @@ STRTOFIX (const char *nptr, char **endptr) shift = RETURN_FRAC_BITS - 4 + exponent - 4 * i; if (shift >= 0) r |= val << shift; - else if (shift <= -4) + else if (shift < -4) extra |= (val != 0); else { diff --git a/ports/sysdeps/powerpc/powerpc32/e500/fpu/tst-spepim.c b/ports/sysdeps/powerpc/powerpc32/e500/fpu/tst-spepim.c new file mode 100644 index 000000000..acac00e12 --- /dev/null +++ b/ports/sysdeps/powerpc/powerpc32/e500/fpu/tst-spepim.c @@ -0,0 +1,494 @@ +/* Test SPE PIM functions. + Copyright (C) 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Joseph Myers , 2007. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include +#include +#include + +typedef int16_t sint16_t; +typedef int32_t sint32_t; +typedef int64_t sint64_t; + +#define SAT_MAX_U16 0xffff +#define SAT_MAX_U32 0xffffffffu +#define SAT_MAX_U64 0xffffffffffffffffull +#define SAT_MAX_S16 0x7fff +#define SAT_MAX_S32 0x7fffffff +#define SAT_MAX_S64 0x7fffffffffffffffll +#define SAT_MIN_S16 (-SAT_MAX_S16 - 1) +#define SAT_MIN_S32 (-SAT_MAX_S32 - 1) +#define SAT_MIN_S64 (-SAT_MAX_S64 - 1) + +/* Test results for a single rounding mode. For each type of result, + store the expected result and the expected errno. */ +struct res { + sint16_t s16; + int es16; + sint32_t s32; + int es32; + sint64_t s64; + int es64; + uint16_t u16; + int eu16; + uint32_t u32; + int eu32; + uint64_t u64; + int eu64; +}; + +struct testcase { + /* String to test. */ + const char *s; + /* Number of junk characters at end. */ + size_t njunk; + /* Expected results for rounding to nearest, zero, upward and + downward. */ + struct res res[4]; +}; + +/* Saturating value. */ +#define SAT(VAL) VAL, ERANGE +/* Unsaturating value. */ +#define UNSAT(VAL) VAL, 0 +/* Values saturating for both signed and unsigned. */ +#define SAT6(VAL0, VAL1, VAL2, VAL3, VAL4, VAL5) \ + { \ + SAT (VAL0), SAT (VAL1), SAT (VAL2), \ + SAT (VAL3), SAT (VAL4), SAT (VAL5) \ + } +#define SAT6_MAX \ + SAT6 (SAT_MAX_S16, SAT_MAX_S32, SAT_MAX_S64, \ + SAT_MAX_U16, SAT_MAX_U32, SAT_MAX_U64) +#define SAT6_MIN \ + SAT6 (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64, 0, 0, 0) +/* Values saturating for unsigned but not signed. */ +#define SATNEG(VAL0, VAL1, VAL2) \ + { \ + UNSAT (VAL0), UNSAT (VAL1), UNSAT (VAL2), \ + SAT (0), SAT (0), SAT (0) \ + } +/* Values not saturating. */ +#define UNSAT6(VAL0, VAL1, VAL2, VAL3, VAL4, VAL5) \ + { \ + UNSAT (VAL0), UNSAT (VAL1), UNSAT (VAL2), \ + UNSAT (VAL3), UNSAT (VAL4), UNSAT (VAL5) \ + } +/* Results not depending on rounding mode. */ +#define EXACT_SAT6_MAX \ + { \ + SAT6_MAX, \ + SAT6_MAX, \ + SAT6_MAX, \ + SAT6_MAX \ + } +#define EXACT_SAT6_MIN \ + { \ + SAT6_MIN, \ + SAT6_MIN, \ + SAT6_MIN, \ + SAT6_MIN \ + } +#define EXACT_SATNEG(VAL0, VAL1, VAL2) \ + { \ + SATNEG (VAL0, VAL1, VAL2), \ + SATNEG (VAL0, VAL1, VAL2), \ + SATNEG (VAL0, VAL1, VAL2), \ + SATNEG (VAL0, VAL1, VAL2) \ + } +#define EXACT_UNSAT6(VAL0, VAL1, VAL2, VAL3, VAL4, VAL5) \ + { \ + UNSAT6 (VAL0, VAL1, VAL2, VAL3, VAL4, VAL5), \ + UNSAT6 (VAL0, VAL1, VAL2, VAL3, VAL4, VAL5), \ + UNSAT6 (VAL0, VAL1, VAL2, VAL3, VAL4, VAL5), \ + UNSAT6 (VAL0, VAL1, VAL2, VAL3, VAL4, VAL5) \ + } + +static const struct testcase tests[] = { + /* Strings evaluating to 0, including INF and NaN (not supported by + SPE PIM functions). */ + { "", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "00", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "+0", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "-0", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0.0", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { ".0", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0.", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { " \n-0.", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0e100000000000000000", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { " \t 0e-100000000000000000", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0x0", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0x0.", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0x.0", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0x0.p100000000000000000", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "-0x0.p002000000000000000", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0x.0p-100000000000000000", 0, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0x", 1, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0x.", 2, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { ".", 1, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { " .", 2, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "+.", 2, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { " +.", 3, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { " -.", 3, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0xp", 2, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0x.p", 3, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "+0x.p", 3, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "-0x.p0", 4, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "0x0q", 1, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "INF", 3, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + { "nan", 3, EXACT_UNSAT6 (0, 0, 0, 0, 0, 0) }, + /* Strings evaluating to 1.0 or greater, saturating unconditionally. */ + { "1", 0, EXACT_SAT6_MAX }, + { "1.0", 0, EXACT_SAT6_MAX }, + { "1e0", 0, EXACT_SAT6_MAX }, + { "10e-1", 0, EXACT_SAT6_MAX }, + { "0.1e1", 0, EXACT_SAT6_MAX }, + { "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-100", 0, EXACT_SAT6_MAX }, + { "2", 0, EXACT_SAT6_MAX }, + { "0x1", 0, EXACT_SAT6_MAX }, + { "0x2p-1", 0, EXACT_SAT6_MAX }, + { "0x.8p1", 0, EXACT_SAT6_MAX }, + { "0x.40p2", 0, EXACT_SAT6_MAX }, + /* Strings evaluating to less than -1.0, saturating unconditionally. */ + { "-1.1", 0, EXACT_SAT6_MIN }, + { "-.11e1", 0, EXACT_SAT6_MIN }, + { "-11e-1", 0, EXACT_SAT6_MIN }, + { "-100", 0, EXACT_SAT6_MIN }, + { "-2", 0, EXACT_SAT6_MIN }, + { "-0x1.00000000000000000000000001", 0, EXACT_SAT6_MIN }, + { "-0x2.00000000000000000000000001p-1", 0, EXACT_SAT6_MIN }, + { "-0x0.80000000000000000000000001p1", 0, EXACT_SAT6_MIN }, + { "-1.000000000000000000000000000000000000000000000000000000000000000000000000000000001", 0, EXACT_SAT6_MIN }, + /* Strings evaluating to -1.0 exactly, saturating for unsigned but + exactly representable for signed. */ + { "-1", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-1e", 1, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-1.0", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-10e-1", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-.1e+1", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-.0000000001e+10", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-10000000000e-10", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-0x1", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-0x1p+", 2, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-0x2p-1", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-0x4.0p-2", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-0x8.p-3", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-0x10p-4", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-0x.8p1", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-0x.4p+2", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-0x.2p+3", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-0x.1p+4", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + { "-0x.08p5", 0, EXACT_SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) }, + /* Strings evaluating to exactly representable values between -1.0 + and 0.0, saturating for unsigned. */ + { "-0.5", 0, EXACT_SATNEG (-0x4000, -0x40000000, -0x4000000000000000ll) }, + { "-0.5e-", 2, EXACT_SATNEG (-0x4000, -0x40000000, -0x4000000000000000ll) }, + { "-05e-1", 0, EXACT_SATNEG (-0x4000, -0x40000000, -0x4000000000000000ll) }, + { "-05000000000e-10", 0, EXACT_SATNEG (-0x4000, -0x40000000, -0x4000000000000000ll) }, + { "-0.5e0", 0, EXACT_SATNEG (-0x4000, -0x40000000, -0x4000000000000000ll) }, + { "-0.00000000005e10", 0, EXACT_SATNEG (-0x4000, -0x40000000, -0x4000000000000000ll) }, + { "-0x.8", 0, EXACT_SATNEG (-0x4000, -0x40000000, -0x4000000000000000ll) }, + { "-0x1p-1", 0, EXACT_SATNEG (-0x4000, -0x40000000, -0x4000000000000000ll) }, + { "-0x.4p1", 0, EXACT_SATNEG (-0x4000, -0x40000000, -0x4000000000000000ll) }, + { "-0.25", 0, EXACT_SATNEG (-0x2000, -0x20000000, -0x2000000000000000ll) }, + { "-2.5e-1", 0, EXACT_SATNEG (-0x2000, -0x20000000, -0x2000000000000000ll) }, + { "-0.75", 0, EXACT_SATNEG (-0x6000, -0x60000000, -0x6000000000000000ll) }, + { "-0.000030517578125", 0, EXACT_SATNEG (-0x0001, -0x00010000, -0x0001000000000000ll) }, + { "-0.376739501953125", 0, EXACT_SATNEG (-12345, -12345*0x10000, -12345*0x1000000000000ll) }, + { "-0x.dcba", 0, EXACT_SATNEG (-0x6e5d, -0x6e5d0000, -0x6e5d000000000000ll) }, + { "-0xd.cbap-4", 0, EXACT_SATNEG (-0x6e5d, -0x6e5d0000, -0x6e5d000000000000ll) }, + /* Strings evaluating to exactly representable values between 0.0 + and 1.0. */ + { "0.5", 0, EXACT_UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000000ull) }, + { "0.5e-", 2, EXACT_UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000000ull) }, + { "05e-1", 0, EXACT_UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000000ull) }, + { "05000000000e-10", 0, EXACT_UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000000ull) }, + { "0.5e0", 0, EXACT_UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000000ull) }, + { "0.00000000005e10", 0, EXACT_UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000000ull) }, + { "0x.8", 0, EXACT_UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000000ull) }, + { "0x1p-1", 0, EXACT_UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000000ull) }, + { "0x.4p1", 0, EXACT_UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000000ull) }, + { "0.25", 0, EXACT_UNSAT6 (0x2000, 0x20000000, 0x2000000000000000ll, 0x4000, 0x40000000u, 0x4000000000000000ull) }, + { "2.5e-1", 0, EXACT_UNSAT6 (0x2000, 0x20000000, 0x2000000000000000ll, 0x4000, 0x40000000u, 0x4000000000000000ull) }, + { "0.75", 0, EXACT_UNSAT6 (0x6000, 0x60000000, 0x6000000000000000ll, 0xc000, 0xc0000000u, 0xc000000000000000ull) }, + { "0.000030517578125", 0, EXACT_UNSAT6 (0x0001, 0x00010000, 0x0001000000000000ll, 0x0002, 0x00020000u, 0x0002000000000000ull) }, + { "0.376739501953125", 0, EXACT_UNSAT6 (12345, 12345*0x10000, 12345*0x1000000000000ll, 12345*0x2, 12345*0x20000u, 12345*0x2000000000000ull) }, + { "0x.dcba", 0, EXACT_UNSAT6 (0x6e5d, 0x6e5d0000, 0x6e5d000000000000ll, 0xdcba, 0xdcba0000u, 0xdcba000000000000ull) }, + { "0xd.cbap-4", 0, EXACT_UNSAT6 (0x6e5d, 0x6e5d0000, 0x6e5d000000000000ll, 0xdcba, 0xdcba0000u, 0xdcba000000000000ull) }, + /* Strings evaluating to values between 0.0 and 1.0, depending on + rounding mode. */ + { "0.1", 0, + { + UNSAT6 (0xccd, 0xccccccd, 0xccccccccccccccdll, 0x199a, 0x1999999au, 0x199999999999999aull), + UNSAT6 (0xccc, 0xccccccc, 0xcccccccccccccccll, 0x1999, 0x19999999u, 0x1999999999999999ull), + UNSAT6 (0xccd, 0xccccccd, 0xccccccccccccccdll, 0x199a, 0x1999999au, 0x199999999999999aull), + UNSAT6 (0xccc, 0xccccccc, 0xcccccccccccccccll, 0x1999, 0x19999999u, 0x1999999999999999ull) + } + }, + { "0.5000152587890625", 0, + { + UNSAT6 (0x4000, 0x40008000, 0x4000800000000000ll, 0x8001, 0x80010000u, 0x8001000000000000ull), + UNSAT6 (0x4000, 0x40008000, 0x4000800000000000ll, 0x8001, 0x80010000u, 0x8001000000000000ull), + UNSAT6 (0x4001, 0x40008000, 0x4000800000000000ll, 0x8001, 0x80010000u, 0x8001000000000000ull), + UNSAT6 (0x4000, 0x40008000, 0x4000800000000000ll, 0x8001, 0x80010000u, 0x8001000000000000ull) + } + }, + { "0.50001525878906250000000000000000000000000000000000000000000000000000000000001", 0, + { + UNSAT6 (0x4001, 0x40008000, 0x4000800000000000ll, 0x8001, 0x80010000u, 0x8001000000000000ull), + UNSAT6 (0x4000, 0x40008000, 0x4000800000000000ll, 0x8001, 0x80010000u, 0x8001000000000000ull), + UNSAT6 (0x4001, 0x40008001, 0x4000800000000001ll, 0x8002, 0x80010001u, 0x8001000000000001ull), + UNSAT6 (0x4000, 0x40008000, 0x4000800000000000ll, 0x8001, 0x80010000u, 0x8001000000000000ull) + } + }, + { "0.50000000000000000008131516293641283255055896006524562835693359375", 0, + { + UNSAT6 (0x4000, 0x40000000, 0x4000000000000001ll, 0x8000, 0x80000000u, 0x8000000000000002ull), + UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000001ull), + UNSAT6 (0x4001, 0x40000001, 0x4000000000000001ll, 0x8001, 0x80000001u, 0x8000000000000002ull), + UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000001ull) + } + }, + { "0.50000000000000000008131516293641283255055896006524562835693359376", 0, + { + UNSAT6 (0x4000, 0x40000000, 0x4000000000000001ll, 0x8000, 0x80000000u, 0x8000000000000002ull), + UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000001ull), + UNSAT6 (0x4001, 0x40000001, 0x4000000000000001ll, 0x8001, 0x80000001u, 0x8000000000000002ull), + UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000001ull) + } + }, + { "0.50000000000000000008131516293641283255055896006524562835693359374", 0, + { + UNSAT6 (0x4000, 0x40000000, 0x4000000000000001ll, 0x8000, 0x80000000u, 0x8000000000000001ull), + UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000001ull), + UNSAT6 (0x4001, 0x40000001, 0x4000000000000001ll, 0x8001, 0x80000001u, 0x8000000000000002ull), + UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000001ull) + } + }, + { "0x0.80000000000000018", 0, + { + UNSAT6 (0x4000, 0x40000000, 0x4000000000000001ll, 0x8000, 0x80000000u, 0x8000000000000002ull), + UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000001ull), + UNSAT6 (0x4001, 0x40000001, 0x4000000000000001ll, 0x8001, 0x80000001u, 0x8000000000000002ull), + UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000001ull) + } + }, + { "0x0.80000000000000017", 0, + { + UNSAT6 (0x4000, 0x40000000, 0x4000000000000001ll, 0x8000, 0x80000000u, 0x8000000000000001ull), + UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000001ull), + UNSAT6 (0x4001, 0x40000001, 0x4000000000000001ll, 0x8001, 0x80000001u, 0x8000000000000002ull), + UNSAT6 (0x4000, 0x40000000, 0x4000000000000000ll, 0x8000, 0x80000000u, 0x8000000000000001ull) + } + }, + /* Strings evaluating to values between -1.0 and 0.0, depending on + rounding mode. */ + { "-0.1", 0, + { + SATNEG (-0xccd, -0xccccccd, -0xccccccccccccccdll), + SATNEG (-0xccc, -0xccccccc, -0xcccccccccccccccll), + SATNEG (-0xccc, -0xccccccc, -0xcccccccccccccccll), + SATNEG (-0xccd, -0xccccccd, -0xccccccccccccccdll) + } + }, + { "-0.5000000000000000001626303258728256651011179201304912567138671875", 0, + { + SATNEG (-0x4000, -0x40000000, -0x4000000000000002ll), + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4001, -0x40000001, -0x4000000000000002ll) + } + }, + { "-0.5000000000000000001626303258728256651011179201304912567138671874", 0, + { + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4001, -0x40000001, -0x4000000000000002ll) + } + }, + { "-0.5000000000000000001626303258728256651011179201304912567138671876", 0, + { + SATNEG (-0x4000, -0x40000000, -0x4000000000000002ll), + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4001, -0x40000001, -0x4000000000000002ll) + } + }, + { "-0x.8000000000000003", 0, + { + SATNEG (-0x4000, -0x40000000, -0x4000000000000002ll), + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4001, -0x40000001, -0x4000000000000002ll) + } + }, + { "-0x.8000000000000002f", 0, + { + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4000, -0x40000000, -0x4000000000000001ll), + SATNEG (-0x4001, -0x40000001, -0x4000000000000002ll) + } + }, + /* Strings evaluating very close to 1.0, saturation depending on + rounding mode. */ + { "0x.fffe1", 0, + { + { UNSAT (0x7fff), UNSAT (0x7fff0800), UNSAT (0x7fff080000000000ll), UNSAT (0xfffe), UNSAT (0xfffe1000u), UNSAT (0xfffe100000000000ull) }, + { UNSAT (0x7fff), UNSAT (0x7fff0800), UNSAT (0x7fff080000000000ll), UNSAT (0xfffe), UNSAT (0xfffe1000u), UNSAT (0xfffe100000000000ull) }, + { SAT (0x7fff), UNSAT (0x7fff0800), UNSAT (0x7fff080000000000ll), UNSAT (0xffff), UNSAT (0xfffe1000u), UNSAT (0xfffe100000000000ull) }, + { UNSAT (0x7fff), UNSAT (0x7fff0800), UNSAT (0x7fff080000000000ll), UNSAT (0xfffe), UNSAT (0xfffe1000u), UNSAT (0xfffe100000000000ull) } + } + }, + { "0x.ffff8", 0, + { + { SAT (0x7fff), UNSAT (0x7fffc000), UNSAT (0x7fffc00000000000ll), SAT (0xffff), UNSAT (0xffff8000u), UNSAT (0xffff800000000000ull) }, + { UNSAT (0x7fff), UNSAT (0x7fffc000), UNSAT (0x7fffc00000000000ll), UNSAT (0xffff), UNSAT (0xffff8000u), UNSAT (0xffff800000000000ull) }, + { SAT (0x7fff), UNSAT (0x7fffc000), UNSAT (0x7fffc00000000000ll), SAT (0xffff), UNSAT (0xffff8000u), UNSAT (0xffff800000000000ull) }, + { UNSAT (0x7fff), UNSAT (0x7fffc000), UNSAT (0x7fffc00000000000ll), UNSAT (0xffff), UNSAT (0xffff8000u), UNSAT (0xffff800000000000ull) } + } + }, + { "0x.fffffffffffffffff", 0, + { + { SAT (0x7fff), SAT (0x7fffffff), SAT (0x7fffffffffffffffll), SAT (0xffff), SAT (0xffffffffu), SAT (0xffffffffffffffffull) }, + { UNSAT (0x7fff), UNSAT (0x7fffffff), UNSAT (0x7fffffffffffffffll), UNSAT (0xffff), UNSAT (0xffffffffu), UNSAT (0xffffffffffffffffull) }, + { SAT (0x7fff), SAT (0x7fffffff), SAT (0x7fffffffffffffffll), SAT (0xffff), SAT (0xffffffffu), SAT (0xffffffffffffffffull) }, + { UNSAT (0x7fff), UNSAT (0x7fffffff), UNSAT (0x7fffffffffffffffll), UNSAT (0xffff), UNSAT (0xffffffffu), UNSAT (0xffffffffffffffffull) } + } + }, + /* Strings evaluating very close to -1.0, may round to -1 but only + saturate for unsigned. */ + { "-0x.fffe1", 0, + { + SATNEG (-0x7fff, -0x7fff0800, -0x7fff080000000000ll), + SATNEG (-0x7fff, -0x7fff0800, -0x7fff080000000000ll), + SATNEG (-0x7fff, -0x7fff0800, -0x7fff080000000000ll), + SATNEG (SAT_MIN_S16, -0x7fff0800, -0x7fff080000000000ll) + } + }, + { "-0x.ffffffffffffffff", 0, + { + SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64), + SATNEG (-0x7fff, -0x7fffffff, -0x7fffffffffffffffll), + SATNEG (-0x7fff, -0x7fffffff, -0x7fffffffffffffffll), + SATNEG (SAT_MIN_S16, SAT_MIN_S32, SAT_MIN_S64) + } + } +}; + +static const int rounding_modes[4] = { + FE_TONEAREST, + FE_TOWARDZERO, + FE_UPWARD, + FE_DOWNWARD +}; + +static const char *const mode_names[4] = { + "FE_TONEAREST", + "FE_TOWARDZERO", + "FE_UPWARD", + "FE_DOWNWARD" +}; + +int +main (void) +{ + int passes = 0; + int fails = 0; + size_t i; + for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++) + { + size_t j; + for (j = 0; j < 4; j++) + { + if (fesetround (rounding_modes[j]) != 0) + { + printf ("fesetround (%s) failed.\n", mode_names[j]); + abort (); + } +#define DO_TEST(SU, SZ, PR) \ + do { \ + SU##int##SZ##_t expret = tests[i].res[j].SU##SZ; \ + int experr = tests[i].res[j].e##SU##SZ; \ + size_t explen = strlen (tests[i].s) - tests[i].njunk; \ + SU##int##SZ##_t ret0, ret1; \ + int reterr; \ + size_t retlen; \ + char *ep; \ + errno = 0; \ + ret0 = strto##SU##fix##SZ (tests[i].s, &ep); \ + reterr = errno; \ + retlen = ep - tests[i].s; \ + if (ret0 == expret) \ + passes++; \ + else \ + { \ + fails++; \ + printf ("strto"#SU"fix"#SZ" (\"%s\") in mode %s " \ + "returned %0"PR"x, expected %0"PR"x.\n", \ + tests[i].s, mode_names[j], ret0, expret); \ + } \ + if (reterr == experr) \ + passes++; \ + else \ + { \ + fails++; \ + printf ("strto"#SU"fix"#SZ" (\"%s\") in mode %s " \ + "left errno as %d, expected %d.\n", \ + tests[i].s, mode_names[j], reterr, experr); \ + } \ + if (retlen == explen) \ + passes++; \ + else \ + { \ + fails++; \ + printf ("strto"#SU"fix"#SZ" (\"%s\") in mode %s " \ + "consumed %zu characters, expected %zu.\n", \ + tests[i].s, mode_names[j], retlen, explen); \ + } \ + if (experr == 0) \ + { \ + ret1 = ato##SU##fix##SZ (tests[i].s); \ + if (ret1 == expret) \ + passes++; \ + else \ + { \ + fails++; \ + printf ("ato"#SU"fix"#SZ" (\"%s\") in mode %s " \ + "returned %0"PR"x, expected %0"PR"x.\n", \ + tests[i].s, mode_names[j], ret1, expret); \ + } \ + } \ + } while (0) + DO_TEST (s, 16, "4h"); + DO_TEST (s, 32, "8"); + DO_TEST (s, 64, "16ll"); + DO_TEST (u, 16, "4h"); + DO_TEST (u, 32, "8"); + DO_TEST (u, 64, "16ll"); + } + } + printf ("Number of passes: %d\nNumber of failures: %d\n", passes, fails); + return fails != 0; +} -- cgit v1.2.1