From 88eefd344b3cf4a41284a1dfdaca61667e3a1b4b Mon Sep 17 00:00:00 2001 From: Stefan Liebler Date: Wed, 26 Aug 2015 10:26:24 +0200 Subject: S390: Optimize memchr, rawmemchr and wmemchr. This patch provides optimized versions of memchr, rawmemchr and wmemchr with the z13 vector instructions. ChangeLog: * sysdeps/s390/multiarch/memchr-vx.S: New File. * sysdeps/s390/multiarch/memchr.c: Likewise. * sysdeps/s390/multiarch/rawmemchr-c.c: Likewise. * sysdeps/s390/multiarch/rawmemchr-vx.S: Likewise. * sysdeps/s390/multiarch/rawmemchr.c: Likewise. * sysdeps/s390/multiarch/wmemchr-c.c: Likewise. * sysdeps/s390/multiarch/wmemchr-vx.S: Likewise. * sysdeps/s390/multiarch/wmemchr.c: Likewise. * sysdeps/s390/s390-32/multiarch/memchr.c: Likewise. * sysdeps/s390/s390-64/multiarch/memchr.c: Likewise. * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memchr, wmemchr and rawmemchr functions. * sysdeps/s390/multiarch/ifunc-impl-list-common.c (__libc_ifunc_impl_list_common): Add ifunc test for memchr, rawmemchr and wmemchr. * wcsmbs/wmemchr.c: Use WMEMCHR if defined. * string/test-memchr.c: Add wmemchr support. * wcsmbs/test-wmemchr.c: New File. * wcsmbs/Makefile (strop-tests): Add wmemchr. * benchtests/bench-memchr.c: Add wmemchr support. * benchtests/bench-wmemchr.c: New File. * benchtests/Makefile (wcsmbs-bench): wmemchr. --- string/test-memchr.c | 91 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 34 deletions(-) (limited to 'string') diff --git a/string/test-memchr.c b/string/test-memchr.c index 19c89781b2..fe7d82facb 100644 --- a/string/test-memchr.c +++ b/string/test-memchr.c @@ -1,4 +1,4 @@ -/* Test and measure memchr functions. +/* Test memchr functions. Copyright (C) 1999-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Jakub Jelinek , 1999. @@ -18,28 +18,49 @@ . */ #define TEST_MAIN -#define TEST_NAME "memchr" +#ifndef WIDE +# define TEST_NAME "memchr" +#else +# define TEST_NAME "wmemchr" +#endif /* WIDE */ #include "test-string.h" -typedef char *(*proto_t) (const char *, int, size_t); -char *simple_memchr (const char *, int, size_t); - -IMPL (simple_memchr, 0) -IMPL (memchr, 1) - -char * -simple_memchr (const char *s, int c, size_t n) +#ifndef WIDE +# define MEMCHR memchr +# define CHAR char +# define UCHAR unsigned char +# define SIMPLE_MEMCHR simple_memchr +# define BIG_CHAR CHAR_MAX +# define SMALL_CHAR 127 +#else +# include +# define MEMCHR wmemchr +# define CHAR wchar_t +# define UCHAR wchar_t +# define SIMPLE_MEMCHR simple_wmemchr +# define BIG_CHAR WCHAR_MAX +# define SMALL_CHAR 1273 +#endif /* WIDE */ + +typedef CHAR *(*proto_t) (const CHAR *, int, size_t); +CHAR *SIMPLE_MEMCHR (const CHAR *, int, size_t); + +IMPL (SIMPLE_MEMCHR, 0) +IMPL (MEMCHR, 1) + +CHAR * +SIMPLE_MEMCHR (const CHAR *s, int c, size_t n) { while (n--) - if (*s++ == (char) c) - return (char *) s - 1; + if (*s++ == (CHAR) c) + return (CHAR *) s - 1; return NULL; } static void -do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res) +do_one_test (impl_t *impl, const CHAR *s, int c, size_t n, CHAR *exp_res) { - char *res = CALL (impl, s, c, n); + CHAR *res = CALL (impl, s, c, n); if (res != exp_res) { error (0, 0, "Wrong result in function %s %p %p", impl->name, @@ -53,34 +74,36 @@ static void do_test (size_t align, size_t pos, size_t len, int seek_char) { size_t i; - char *result; + CHAR *result; align &= 7; - if (align + len >= page_size) + if ((align + len) * sizeof (CHAR) >= page_size) return; + CHAR *buf = (CHAR *) (buf1); + for (i = 0; i < len; ++i) { - buf1[align + i] = 1 + 23 * i % 127; - if (buf1[align + i] == seek_char) - buf1[align + i] = seek_char + 1; + buf[align + i] = 1 + 23 * i % SMALL_CHAR; + if (buf[align + i] == seek_char) + buf[align + i] = seek_char + 1; } - buf1[align + len] = 0; + buf[align + len] = 0; if (pos < len) { - buf1[align + pos] = seek_char; - buf1[align + len] = -seek_char; - result = (char *) (buf1 + align + pos); + buf[align + pos] = seek_char; + buf[align + len] = -seek_char; + result = (CHAR *) (buf + align + pos); } else { result = NULL; - buf1[align + len] = seek_char; + buf[align + len] = seek_char; } FOR_EACH_IMPL (impl, 0) - do_one_test (impl, (char *) (buf1 + align), seek_char, len, result); + do_one_test (impl, (CHAR *) (buf + align), seek_char, len, result); } static void @@ -88,8 +111,8 @@ do_random_tests (void) { size_t i, j, n, align, pos, len; int seek_char; - char *result; - unsigned char *p = buf1 + page_size - 512; + CHAR *result; + UCHAR *p = (UCHAR *) (buf1 + page_size) - 512; for (n = 0; n < ITERATIONS; n++) { @@ -101,11 +124,11 @@ do_random_tests (void) if (pos >= len) len = pos + (random () & 7); if (len + align >= 512) - len = 512 - align - (random () & 7); - seek_char = random () & 255; + len = 512 - align - (random () & 7); + seek_char = random () & BIG_CHAR; j = len + align + 64; if (j > 512) - j = 512; + j = 512; for (i = 0; i < j; i++) { @@ -113,7 +136,7 @@ do_random_tests (void) p[i] = seek_char; else { - p[i] = random () & 255; + p[i] = random () & BIG_CHAR; if (i < pos + align && p[i] == seek_char) p[i] = seek_char + 13; } @@ -124,17 +147,17 @@ do_random_tests (void) size_t r = random (); if ((r & 31) == 0) len = ~(uintptr_t) (p + align) - ((r >> 5) & 31); - result = (char *) (p + pos + align); + result = (CHAR *) (p + pos + align); } else result = NULL; FOR_EACH_IMPL (impl, 1) - if (CALL (impl, (char *) (p + align), seek_char, len) != result) + if (CALL (impl, (CHAR *) (p + align), seek_char, len) != result) { error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p", n, impl->name, align, seek_char, len, pos, - CALL (impl, (char *) (p + align), seek_char, len), + CALL (impl, (CHAR *) (p + align), seek_char, len), result, p); ret = 1; } -- cgit v1.2.3