diff options
Diffstat (limited to 'string')
-rw-r--r-- | string/Makefile | 2 | ||||
-rw-r--r-- | string/test-strcmp.c | 180 | ||||
-rw-r--r-- | string/test-wcscmp.c | 2 |
3 files changed, 160 insertions, 24 deletions
diff --git a/string/Makefile b/string/Makefile index f76758f49e..459b2a7f49 100644 --- a/string/Makefile +++ b/string/Makefile @@ -46,7 +46,7 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \ # for -fbounded-pointer compiles. Glibc uses memchr for explicit checks. o-objects.ob := memcpy.o memset.o memchr.o -strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \ +strop-tests := wcscmp memchr memcmp memcpy memmove mempcpy memset memccpy \ stpcpy stpncpy strcat strchr strcmp strcpy strcspn \ strlen strncmp strncpy strpbrk strrchr strspn memmem \ strstr strcasestr strnlen strcasecmp strncasecmp \ diff --git a/string/test-strcmp.c b/string/test-strcmp.c index 769e9828fd..908dc27129 100644 --- a/string/test-strcmp.c +++ b/string/test-strcmp.c @@ -1,7 +1,8 @@ -/* Test and measure strcmp functions. - Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc. +/* Test and measure STRCMP functions. + Copyright (C) 1999, 2002, 2003, 2005, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Jakub Jelinek <jakub@redhat.com>, 1999. + Added wcscmp support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -21,39 +22,63 @@ #define TEST_MAIN #include "test-string.h" +#ifdef WIDE +# include <inttypes.h> +# include <wchar.h> +#endif + +#ifdef WIDE +# define L(str) L##str +# define STRCMP wcscmp +# define STRCPY wcscpy +# define STRLEN wcslen +# define SIMPLE_STRCMP simple_wcscmp +# define STUPID_STRCMP stupid_wcscmp +typedef uint32_t unsigned_element_type; +typedef uint32_t element_type; +typedef int (*proto_t) (const uint32_t *, const uint32_t *); +#else +# define L(str) str +# define STRCMP strcmp +# define STRCPY strcpy +# define STRLEN strlen +# define SIMPLE_STRCMP simple_strcmp +# define STUPID_STRCMP stupid_strcmp +typedef unsigned char unsigned_element_type; +typedef char element_type; typedef int (*proto_t) (const char *, const char *); -int simple_strcmp (const char *, const char *); -int stupid_strcmp (const char *, const char *); - -IMPL (stupid_strcmp, 0) -IMPL (simple_strcmp, 0) -IMPL (strcmp, 1) +#endif int -simple_strcmp (const char *s1, const char *s2) +SIMPLE_STRCMP (const unsigned_element_type *s1, const unsigned_element_type *s2) { int ret; - while ((ret = *(unsigned char *) s1 - *(unsigned char *) s2++) == 0 - && *s1++); + while ((ret = *s1 - *s2++) == 0 && *s1++); return ret; } int -stupid_strcmp (const char *s1, const char *s2) +STUPID_STRCMP (const unsigned_element_type *s1, const unsigned_element_type *s2) { - size_t ns1 = strlen (s1) + 1, ns2 = strlen (s2) + 1; + size_t ns1 = STRLEN (s1) + 1, ns2 = STRLEN (s2) + 1; size_t n = ns1 < ns2 ? ns1 : ns2; int ret = 0; while (n--) - if ((ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) != 0) + if ((ret = *s1++ - *s2++) != 0) break; return ret; } -static void -do_one_test (impl_t *impl, const char *s1, const char *s2, int exp_result) +IMPL (STUPID_STRCMP, 1) +IMPL (SIMPLE_STRCMP, 1) +IMPL (STRCMP, 1) + +static int +check_result (impl_t *impl, + const element_type *s1, const element_type *s2, + int exp_result) { int result = CALL (impl, s1, s2); if ((exp_result == 0 && result != 0) @@ -63,9 +88,20 @@ do_one_test (impl_t *impl, const char *s1, const char *s2, int exp_result) error (0, 0, "Wrong result in function %s %d %d", impl->name, result, exp_result); ret = 1; - return; + return -1; } + return 0; +} + +static void +do_one_test (impl_t *impl, + const element_type *s1, const element_type *s2, + int exp_result) +{ + if (check_result (impl, s1, s2, exp_result) < 0) + return; + if (HP_TIMING_AVAIL) { hp_timing_t start __attribute ((unused)); @@ -90,11 +126,13 @@ do_test (size_t align1, size_t align2, size_t len, int max_char, int exp_result) { size_t i; - char *s1, *s2; + + element_type *s1, *s2; if (len == 0) return; +#ifndef WIDE align1 &= 7; if (align1 + len + 1 >= page_size) return; @@ -106,8 +144,29 @@ do_test (size_t align1, size_t align2, size_t len, int max_char, s1 = (char *) (buf1 + align1); s2 = (char *) (buf2 + align2); +#else + align1 &= 63; + if (align1 + len * 4 + 4 >= page_size) + return; + + align2 &= 63; + if (align2 + len * 4 + 4 >= page_size) + return; + + /* Put them close to the end of page. */ + i = align1 + 4 * len + 8; + s1 = (uint32_t *) (buf1 + ((page_size - i) / 16 * 16) + align1); + i = align2 + 4 * len + 8; + s2 = (uint32_t *) (buf2 + ((page_size - i) / 16 * 16) + align2); + +#endif + for (i = 0; i < len; i++) +#ifndef WIDE s1[i] = s2[i] = 1 + 23 * i % max_char; +#else + s1[i] = s2[i] = 1 + 1023 * i % max_char; +#endif s1[len] = s2[len] = 0; s1[len + 1] = 23; @@ -129,11 +188,21 @@ do_random_tests (void) { size_t i, j, n, align1, align2, pos, len1, len2; int result; - long r; + int r; + +#ifndef WIDE unsigned char *p1 = buf1 + page_size - 512; unsigned char *p2 = buf2 + page_size - 512; - for (n = 0; n < ITERATIONS; n++) +#else + for (size_t a = 0; a < 4; a++) + for (size_t b = 0; b < 4; b++) + { + uint32_t *p1 = (uint32_t *) (buf1 + page_size - 512 * 4 - a); + uint32_t *p2 = (uint32_t *) (buf2 + page_size - 512 * 4 - b); + + for (n = 0; n < ITERATIONS / 2; n++) +#endif { align1 = random () & 31; if (random () & 1) @@ -178,7 +247,11 @@ do_random_tests (void) } result = 0; +#ifndef WIDE memcpy (p2 + align2, p1 + align1, pos); +#else + memcpy (p2 + align2, p1 + align1, 4 * pos); +#endif if (pos < len1) { if (p2[align2 + pos] == p1[align1 + pos]) @@ -198,7 +271,7 @@ do_random_tests (void) FOR_EACH_IMPL (impl, 1) { - r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2)); + r = CALL (impl, p1 + align1, p2 + align2); /* Test whether on 64-bit architectures where ABI requires callee to promote has the promotion been done. */ asm ("" : "=g" (r) : "0" (r)); @@ -206,26 +279,55 @@ do_random_tests (void) || (r < 0 && result >= 0) || (r > 0 && result <= 0)) { - error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p", - n, impl->name, align1, align2, len1, len2, pos, r, result, p1, p2); + error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd) %d != %d, p1 %p p2 %p", + n, impl->name, (size_t) (p1 + align1) & 63, (size_t) (p1 + align2) & 63, len1, len2, pos, r, result, p1, p2); ret = 1; } } } +#ifdef WIDE + } +#endif } +static void +check (void) +{ + const element_type *s1 = (element_type *) (buf1 + 0xb2c); + const element_type *s2 = (element_type *) (buf1 + 0xfd8); + + size_t i1, i2, l1, l2; + int exp_result; + + STRCPY(s1, L"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs"); + STRCPY(s2, L"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkLMNOPQRSTUV"); + + l1 = STRLEN (s1); + l2 = STRLEN (s2); + for (i1 = 0; i1 < l1; i1++) + for (i2 = 0; i2 < l2; i2++) + { + exp_result = SIMPLE_STRCMP (s1 + i1, s2 + i2); + FOR_EACH_IMPL (impl, 0) + check_result (impl, s1 + i1, s2 + i2, exp_result); + } +} + + int test_main (void) { size_t i; test_init (); + check(); printf ("%23s", ""); FOR_EACH_IMPL (impl, 0) printf ("\t%s", impl->name); putchar ('\n'); +#ifndef WIDE for (i = 1; i < 16; ++i) { do_test (i, i, i, 127, 0); @@ -253,6 +355,38 @@ test_main (void) do_test (2 * i, i, 8 << i, 254, -1); } +#else + for (i = 1; i < 32; ++i) + { + do_test (i, i, i, 127, 0); + do_test (i, i, i, 127, 1); + do_test (i, i, i, 127, -1); + } + + for (i = 1; i < 12; ++i) + { + do_test (0, 0, 2 << i, 127, 0); + do_test (0, 0, 2 << i, 10000, 0); + do_test (0, 0, 2 << i, 127, 1); + do_test (0, 0, 2 << i, 10000, 1); + do_test (0, 0, 2 << i, 127, -1); + do_test (0, 0, 2 << i, 10000, -1); + do_test (0, 4 * i, 2 << i, 127, 1); + do_test (4 * i, 4 * i + 4, 2 << i, 10000, 1); + } + + for (i = 1; i < 9; ++i) + { + do_test (i, 2 * i, 8 << i, 10000, 0); + do_test (8 * i, 4 * i, 8 << i, 20000, 0); + do_test (i, 2 * i, 8 << i, 30000, 1); + do_test (2 * i, i, 8 << i, 10000, 1); + do_test (4 * i, 4 * i + 4, 8 << i, 20000, -1); + do_test (2 * i, i, 8 << i, 30000, -1); + do_test (4 * i + 4, 4 * i, 8 << i, 10000, 1); + } +#endif + do_random_tests (); return ret; } diff --git a/string/test-wcscmp.c b/string/test-wcscmp.c new file mode 100644 index 0000000000..ac98e6d1d8 --- /dev/null +++ b/string/test-wcscmp.c @@ -0,0 +1,2 @@ +#define WIDE 1 +#include "test-strcmp.c" |