2010-11-09 H.J. Lu <hongjiu.lu@intel.com>
[BZ #12205]
* string/test-strncasecmp.c (check_result): New function.
(do_one_test): Use it.
(check1): New function.
(test_main): Use it.
* sysdeps/i386/i686/multiarch/strcmp.S (nibble_ashr_use_sse4_2_exit):
Support strcasecmp and strncasecmp.
2010-10-03 Ulrich Drepper <drepper@gmail.com>
[BZ #12077]
* sysdeps/x86_64/strcmp.S: Fix handling of remaining bytes in buffer
for strncmp and strncasecmp.
* string/stratcliff.c: Add tests for strcmp and strncmp.
* wcsmbs/wcsatcliff.c: Adjust for stratcliff change.
2010-09-20 Ulrich Drepper <drepper@redhat.com>
* sysdeps/x86_64/strcmp.S: Fix another type in strncasecmp limit
detection.
2010-08-19 Ulrich Drepper <drepper@redhat.com>
* sysdeps/x86_64/multiarch/strcmp.S: Fix two typos in strncasecmp
handling.
2010-08-15 Ulrich Drepper <drepper@redhat.com>
* sysdeps/x86_64/strcmp.S: Use correct register for fourth parameter
of strncasecmp_l.
* sysdeps/multiarch/strcmp.S: Likewise.
2010-08-14 Ulrich Drepper <drepper@redhat.com>
* sysdeps/x86_64/Makefile [subdir=string] (sysdep_routines): Add
strncase_l-nonascii.
* sysdeps/x86_64/multiarch/Makefile [subdir=string] (sysdep_routines):
Add strncase_l-ssse3.
* sysdeps/x86_64/multiarch/strcmp.S: Prepare for use as strncasecmp.
* sysdeps/x86_64/strcmp.S: Likewise.
* sysdeps/x86_64/multiarch/strncase_l-ssse3.S: New file.
* sysdeps/x86_64/multiarch/strncase_l.S: New file.
* sysdeps/x86_64/strncase.S: New file.
* sysdeps/x86_64/strncase_l-nonascii.c: New file.
* sysdeps/x86_64/strncase_l.S: New file.
* string/Makefile (strop-tests): Add strncasecmp.
* string/test-strncasecmp.c: New file.
* sysdeps/x86_64/strcasecmp_l-nonascii.c: Add prototype to avoid
warning.
* sysdeps/x86_64/strcmp.S: Move definition of NO_NOLOCALE_ALIAS to...
* sysdeps/x86_64/multiarch/strcasecmp_l-ssse3.S: ... here.
2010-07-31 Ulrich Drepper <drepper@redhat.com>
* sysdeps/x86_64/multiarch/Makefile [subdir=string] (sysdep_routines):
Add strcasecmp_l-ssse3.
* sysdeps/x86_64/multiarch/strcmp.S: Add support to compile for
strcasecmp.
* sysdeps/x86_64/strcmp.S: Allow more flexible compiling of strcasecmp.
* sysdeps/x86_64/multiarch/strcasecmp_l.S: New file.
* sysdeps/x86_64/multiarch/strcasecmp_l-ssse3.S: New file.
2010-07-30 Ulrich Drepper <drepper@redhat.com>
* sysdeps/x86_64/multiarch/strcmp.S: Pretty printing.
* string/Makefile (strop-tests): Add strcasecmp.
* sysdeps/x86_64/Makefile [subdir=string] (sysdep_routines): Add
strcasecmp_l-nonascii.
(gen-as-const-headers): Add locale-defines.sym.
* sysdeps/x86_64/strcmp.S: Add support for strcasecmp implementation.
* sysdeps/x86_64/strcasecmp.S: New file.
* sysdeps/x86_64/strcasecmp_l.S: New file.
* sysdeps/x86_64/strcasecmp_l-nonascii.c: New file.
* sysdeps/x86_64/locale-defines.sym: New file.
* string/test-strcasecmp.c: New file.
* string/test-strcasestr.c: Test both ends of the range of characters.
* sysdeps/x86_64/multiarch/strstr.c: Fix UCHIGH definition.
2010-07-26 Ulrich Drepper <drepper@redhat.com>
* string/test-strnlen.c: New file.
* string/Makefile (strop-tests): Add strnlen.
* string/tester.c (test_strnlen): Add a few more test cases.
* string/tst-strlen.c: Better error reporting.
* sysdeps/x86_64/strnlen.S: New file.
2010-07-24 Ulrich Drepper <drepper@redhat.com>
* sysdeps/x86_64/multiarch/strstr.c (__m128i_strloadu_tolower): Use
lower-latency instructions.
2010-07-23 Ulrich Drepper <drepper@redhat.com>
* string/test-strcasestr.c: New file.
* string/test-strstr.c: New file.
* string/Makefile (strop-tests): Add strstr and strcasestr.
* string/str-two-way.h: Don't undefine MAX.
* string/strcasestr.c: Don't define alias if NO_ALIAS is defined.
2010-07-21 Andreas Schwab <schwab@redhat.com>
* sysdeps/i386/i686/multiarch/Makefile (sysdep_routines): Add
strcasestr-nonascii.
(CFLAGS-strcasestr-nonascii.c): Define.
* sysdeps/i386/i686/multiarch/strcasestr-nonascii.c: New file.
* sysdeps/x86_64/multiarch/strcasestr-nonascii.c (STRSTR_SSE42):
Remove unused attribute.
2010-07-16 Ulrich Drepper <drepper@redhat.com>
* sysdeps/x86_64/multiarch/strstr.c: Rewrite to avoid indirect function
call in strcasestr.
* sysdeps/x86_64/multiarch/strcasestr.c: Declare
__strcasestr_sse42_nonascii.
* sysdeps/x86_64/multiarch/Makefile: Add rules to build
strcasestr-nonascii.c.
* sysdeps/x86_64/multiarch/strcasestr-nonascii.c: New file.
Index: glibc-2.12-2-gc4ccff1/string/Makefile
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/string/Makefile
+++ glibc-2.12-2-gc4ccff1/string/Makefile
@@ -48,7 +48,8 @@ o-objects.ob := memcpy.o memset.o memchr
strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \
stpcpy stpncpy strcat strchr strcmp strcpy strcspn \
- strlen strncmp strncpy strpbrk strrchr strspn memmem
+ strlen strncmp strncpy strpbrk strrchr strspn memmem \
+ strstr strcasestr strnlen strcasecmp strncasecmp
tests := tester inl-tester noinl-tester testcopy test-ffs \
tst-strlen stratcliff tst-svc tst-inlcall \
bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \
Index: glibc-2.12-2-gc4ccff1/string/str-two-way.h
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/string/str-two-way.h
+++ glibc-2.12-2-gc4ccff1/string/str-two-way.h
@@ -426,5 +426,4 @@ two_way_long_needle (const unsigned char
#undef AVAILABLE
#undef CANON_ELEMENT
#undef CMP_FUNC
-#undef MAX
#undef RETURN_TYPE
Index: glibc-2.12-2-gc4ccff1/string/stratcliff.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/string/stratcliff.c
+++ glibc-2.12-2-gc4ccff1/string/stratcliff.c
@@ -47,6 +47,8 @@
# define MEMCPY memcpy
# define MEMPCPY mempcpy
# define MEMCHR memchr
+# define STRCMP strcmp
+# define STRNCMP strncmp
#endif
@@ -277,7 +279,74 @@ do_test (void)
adr[inner] = L('T');
}
- }
+ }
+
+ /* strcmp/wcscmp tests */
+ for (outer = 1; outer < 32; ++outer)
+ for (middle = 0; middle < 16; ++middle)
+ {
+ MEMSET (adr + middle, L('T'), 256);
+ adr[256] = L('\0');
+ MEMSET (dest + nchars - outer, L('T'), outer - 1);
+ dest[nchars - 1] = L('\0');
+
+ if (STRCMP (adr + middle, dest + nchars - outer) <= 0)
+ {
+ printf ("%s 1 flunked for outer = %d, middle = %d\n",
+ STRINGIFY (STRCMP), outer, middle);
+ result = 1;
+ }
+
+ if (STRCMP (dest + nchars - outer, adr + middle) >= 0)
+ {
+ printf ("%s 2 flunked for outer = %d, middle = %d\n",
+ STRINGIFY (STRCMP), outer, middle);
+ result = 1;
+ }
+ }
+
+ /* strncmp/wcsncmp tests */
+ for (outer = 1; outer < 32; ++outer)
+ for (middle = 0; middle < 16; ++middle)
+ {
+ MEMSET (adr + middle, L('T'), 256);
+ adr[256] = L('\0');
+ MEMSET (dest + nchars - outer, L('T'), outer - 1);
+ dest[nchars - 1] = L('U');
+
+ for (inner = 0; inner < outer; ++inner)
+ {
+ if (STRNCMP (adr + middle, dest + nchars - outer, inner) != 0)
+ {
+ printf ("%s 1 flunked for outer = %d, middle = %d, "
+ "inner = %d\n",
+ STRINGIFY (STRNCMP), outer, middle, inner);
+ result = 1;
+ }
+
+ if (STRNCMP (dest + nchars - outer, adr + middle, inner) != 0)
+ {
+ printf ("%s 2 flunked for outer = %d, middle = %d, "
+ "inner = %d\n",
+ STRINGIFY (STRNCMP), outer, middle, inner);
+ result = 1;
+ }
+ }
+
+ if (STRNCMP (adr + middle, dest + nchars - outer, outer) >= 0)
+ {
+ printf ("%s 1 flunked for outer = %d, middle = %d, full\n",
+ STRINGIFY (STRNCMP), outer, middle);
+ result = 1;
+ }
+
+ if (STRNCMP (dest + nchars - outer, adr + middle, outer) <= 0)
+ {
+ printf ("%s 2 flunked for outer = %d, middle = %d, full\n",
+ STRINGIFY (STRNCMP), outer, middle);
+ result = 1;
+ }
+ }
/* strncpy/wcsncpy tests */
adr[nchars - 1] = L('T');
Index: glibc-2.12-2-gc4ccff1/string/strcasestr.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/string/strcasestr.c
+++ glibc-2.12-2-gc4ccff1/string/strcasestr.c
@@ -103,4 +103,6 @@ STRCASESTR (const char *haystack_start,
#undef LONG_NEEDLE_THRESHOLD
+#ifndef NO_ALIAS
weak_alias (__strcasestr, strcasestr)
+#endif
Index: glibc-2.12-2-gc4ccff1/string/test-strcasecmp.c
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/string/test-strcasecmp.c
@@ -0,0 +1,276 @@
+/* Test and measure strcasecmp functions.
+ Copyright (C) 1999, 2002, 2003, 2005, 2010 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+ 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 <ctype.h>
+#define TEST_MAIN
+#include "test-string.h"
+
+typedef int (*proto_t) (const char *, const char *);
+static int simple_strcasecmp (const char *, const char *);
+static int stupid_strcasecmp (const char *, const char *);
+
+IMPL (stupid_strcasecmp, 0)
+IMPL (simple_strcasecmp, 0)
+IMPL (strcasecmp, 1)
+
+static int
+simple_strcasecmp (const char *s1, const char *s2)
+{
+ int ret;
+
+ while ((ret = ((unsigned char) tolower (*s1)
+ - (unsigned char) tolower (*s2))) == 0
+ && *s1++)
+ ++s2;
+ return ret;
+}
+
+static int
+stupid_strcasecmp (const char *s1, const char *s2)
+{
+ 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) tolower (*s1)
+ - (unsigned char) tolower (*s2))) != 0)
+ break;
+ ++s1;
+ ++s2;
+ }
+ return ret;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, int exp_result)
+{
+ int result = CALL (impl, s1, s2);
+ if ((exp_result == 0 && result != 0)
+ || (exp_result < 0 && result >= 0)
+ || (exp_result > 0 && result <= 0))
+ {
+ error (0, 0, "Wrong result in function %s %d %d", impl->name,
+ result, exp_result);
+ ret = 1;
+ return;
+ }
+
+ if (HP_TIMING_AVAIL)
+ {
+ hp_timing_t start __attribute ((unused));
+ hp_timing_t stop __attribute ((unused));
+ hp_timing_t best_time = ~ (hp_timing_t) 0;
+ size_t i;
+
+ for (i = 0; i < 32; ++i)
+ {
+ HP_TIMING_NOW (start);
+ CALL (impl, s1, s2);
+ HP_TIMING_NOW (stop);
+ HP_TIMING_BEST (best_time, start, stop);
+ }
+
+ printf ("\t%zd", (size_t) best_time);
+ }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char,
+ int exp_result)
+{
+ size_t i;
+ char *s1, *s2;
+
+ if (len == 0)
+ return;
+
+ align1 &= 7;
+ if (align1 + len + 1 >= page_size)
+ return;
+
+ align2 &= 7;
+ if (align2 + len + 1 >= page_size)
+ return;
+
+ s1 = (char *) (buf1 + align1);
+ s2 = (char *) (buf2 + align2);
+
+ for (i = 0; i < len; i++)
+ {
+ s1[i] = toupper (1 + 23 * i % max_char);
+ s2[i] = tolower (s1[i]);
+ }
+
+ s1[len] = s2[len] = 0;
+ s1[len + 1] = 23;
+ s2[len + 1] = 24 + exp_result;
+ if ((s2[len - 1] == 'z' && exp_result == -1)
+ || (s2[len - 1] == 'a' && exp_result == 1))
+ s1[len - 1] += exp_result;
+ else
+ s2[len - 1] -= exp_result;
+
+ if (HP_TIMING_AVAIL)
+ printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
+
+ FOR_EACH_IMPL (impl, 0)
+ do_one_test (impl, s1, s2, exp_result);
+
+ if (HP_TIMING_AVAIL)
+ putchar ('\n');
+}
+
+static void
+do_random_tests (void)
+{
+ size_t i, j, n, align1, align2, pos, len1, len2;
+ int result;
+ long r;
+ unsigned char *p1 = buf1 + page_size - 512;
+ unsigned char *p2 = buf2 + page_size - 512;
+
+ for (n = 0; n < ITERATIONS; n++)
+ {
+ align1 = random () & 31;
+ if (random () & 1)
+ align2 = random () & 31;
+ else
+ align2 = align1 + (random () & 24);
+ pos = random () & 511;
+ j = align1 > align2 ? align1 : align2;
+ if (pos + j >= 511)
+ pos = 510 - j - (random () & 7);
+ len1 = random () & 511;
+ if (pos >= len1 && (random () & 1))
+ len1 = pos + (random () & 7);
+ if (len1 + j >= 512)
+ len1 = 511 - j - (random () & 7);
+ if (pos >= len1)
+ len2 = len1;
+ else
+ len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0);
+ j = (pos > len2 ? pos : len2) + align1 + 64;
+ if (j > 512)
+ j = 512;
+ for (i = 0; i < j; ++i)
+ {
+ p1[i] = tolower (random () & 255);
+ if (i < len1 + align1 && !p1[i])
+ {
+ p1[i] = tolower (random () & 255);
+ if (!p1[i])
+ p1[i] = tolower (1 + (random () & 127));
+ }
+ }
+ for (i = 0; i < j; ++i)
+ {
+ p2[i] = toupper (random () & 255);
+ if (i < len2 + align2 && !p2[i])
+ {
+ p2[i] = toupper (random () & 255);
+ if (!p2[i])
+ toupper (p2[i] = 1 + (random () & 127));
+ }
+ }
+
+ result = 0;
+ memcpy (p2 + align2, p1 + align1, pos);
+ if (pos < len1)
+ {
+ if (tolower (p2[align2 + pos]) == p1[align1 + pos])
+ {
+ p2[align2 + pos] = toupper (random () & 255);
+ if (tolower (p2[align2 + pos]) == p1[align1 + pos])
+ p2[align2 + pos] = toupper (p1[align1 + pos]
+ + 3 + (random () & 127));
+ }
+
+ if (p1[align1 + pos] < tolower (p2[align2 + pos]))
+ result = -1;
+ else
+ result = 1;
+ }
+ p1[len1 + align1] = 0;
+ p2[len2 + align2] = 0;
+
+ FOR_EACH_IMPL (impl, 1)
+ {
+ r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2));
+ /* Test whether on 64-bit architectures where ABI requires
+ callee to promote has the promotion been done. */
+ asm ("" : "=g" (r) : "0" (r));
+ if ((r == 0 && result)
+ || (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);
+ ret = 1;
+ }
+ }
+ }
+}
+
+int
+test_main (void)
+{
+ size_t i;
+
+ test_init ();
+
+ printf ("%23s", "");
+ FOR_EACH_IMPL (impl, 0)
+ printf ("\t%s", impl->name);
+ putchar ('\n');
+
+ for (i = 1; i < 16; ++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 < 10; ++i)
+ {
+ do_test (0, 0, 2 << i, 127, 0);
+ do_test (0, 0, 2 << i, 254, 0);
+ do_test (0, 0, 2 << i, 127, 1);
+ do_test (0, 0, 2 << i, 254, 1);
+ do_test (0, 0, 2 << i, 127, -1);
+ do_test (0, 0, 2 << i, 254, -1);
+ }
+
+ for (i = 1; i < 8; ++i)
+ {
+ do_test (i, 2 * i, 8 << i, 127, 0);
+ do_test (2 * i, i, 8 << i, 254, 0);
+ do_test (i, 2 * i, 8 << i, 127, 1);
+ do_test (2 * i, i, 8 << i, 254, 1);
+ do_test (i, 2 * i, 8 << i, 127, -1);
+ do_test (2 * i, i, 8 << i, 254, -1);
+ }
+
+ do_random_tests ();
+ return ret;
+}
+
+#include "../test-skeleton.c"
Index: glibc-2.12-2-gc4ccff1/string/test-strcasestr.c
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/string/test-strcasestr.c
@@ -0,0 +1,197 @@
+/* Test and measure strcasestr functions.
+ Copyright (C) 2010 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2010.
+
+ 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. */
+
+#define TEST_MAIN
+#include "test-string.h"
+
+
+#define STRCASESTR simple_strcasestr
+#define NO_ALIAS
+#define __strncasecmp strncasecmp
+#include "strcasestr.c"
+
+
+static char *
+stupid_strcasestr (const char *s1, const char *s2)
+{
+ ssize_t s1len = strlen (s1);
+ ssize_t s2len = strlen (s2);
+
+ if (s2len > s1len)
+ return NULL;
+
+ for (ssize_t i = 0; i <= s1len - s2len; ++i)
+ {
+ size_t j;
+ for (j = 0; j < s2len; ++j)
+ if (tolower (s1[i + j]) != tolower (s2[j]))
+ break;
+ if (j == s2len)
+ return (char *) s1 + i;
+ }
+
+ return NULL;
+}
+
+
+typedef char *(*proto_t) (const char *, const char *);
+
+IMPL (stupid_strcasestr, 0)
+IMPL (simple_strcasestr, 0)
+IMPL (strcasestr, 1)
+
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+{
+ char *result = CALL (impl, s1, s2);
+ if (result != exp_result)
+ {
+ error (0, 0, "Wrong result in function %s %s %s", impl->name,
+ result, exp_result);
+ ret = 1;
+ return;
+ }
+
+ if (HP_TIMING_AVAIL)
+ {
+ hp_timing_t start __attribute ((unused));
+ hp_timing_t stop __attribute ((unused));
+ hp_timing_t best_time = ~(hp_timing_t) 0;
+ size_t i;
+
+ for (i = 0; i < 32; ++i)
+ {
+ HP_TIMING_NOW (start);
+ CALL (impl, s1, s2);
+ HP_TIMING_NOW (stop);
+ HP_TIMING_BEST (best_time, start, stop);
+ }
+
+ printf ("\t%zd", (size_t) best_time);
+ }
+}
+
+
+static void
+do_test (size_t align1, size_t align2, size_t len1, size_t len2,
+ int fail)
+{
+ char *s1 = (char *) (buf1 + align1);
+ char *s2 = (char *) (buf2 + align2);
+
+ static const char d[] = "1234567890abcxyz";
+#define dl (sizeof (d) - 1)
+ char *ss2 = s2;
+ for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0)
+ {
+ size_t t = l > dl ? dl : l;
+ ss2 = mempcpy (ss2, d, t);
+ }
+ s2[len2] = '\0';
+
+ if (fail)
+ {
+ char *ss1 = s1;
+ for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0)
+ {
+ size_t t = l > dl ? dl : l;
+ memcpy (ss1, d, t);
+ ++ss1[len2 > 7 ? 7 : len2 - 1];
+ ss1 += t;
+ }
+ }
+ else
+ {
+ memset (s1, '0', len1);
+ for (size_t i = 0; i < len2; ++i)
+ s1[len1 - len2 + i] = toupper (s2[i]);
+ }
+ s1[len1] = '\0';
+
+ if (HP_TIMING_AVAIL)
+ printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:",
+ len1, len2, align1, align2, fail ? "fail" : "found");
+
+ FOR_EACH_IMPL (impl, 0)
+ do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2);
+
+ if (HP_TIMING_AVAIL)
+ putchar ('\n');
+}
+
+
+static int
+test_main (void)
+{
+ test_init ();
+
+ printf ("%23s", "");
+ FOR_EACH_IMPL (impl, 0)
+ printf ("\t%s", impl->name);
+ putchar ('\n');
+
+ for (size_t klen = 2; klen < 32; ++klen)
+ for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen)
+ {
+ do_test (0, 0, hlen, klen, 0);
+ do_test (0, 0, hlen, klen, 1);
+ do_test (0, 3, hlen, klen, 0);
+ do_test (0, 3, hlen, klen, 1);
+ do_test (0, 9, hlen, klen, 0);
+ do_test (0, 9, hlen, klen, 1);
+ do_test (0, 15, hlen, klen, 0);
+ do_test (0, 15, hlen, klen, 1);
+
+ do_test (3, 0, hlen, klen, 0);
+ do_test (3, 0, hlen, klen, 1);
+ do_test (3, 3, hlen, klen, 0);
+ do_test (3, 3, hlen, klen, 1);
+ do_test (3, 9, hlen, klen, 0);
+ do_test (3, 9, hlen, klen, 1);
+ do_test (3, 15, hlen, klen, 0);
+ do_test (3, 15, hlen, klen, 1);
+
+ do_test (9, 0, hlen, klen, 0);
+ do_test (9, 0, hlen, klen, 1);
+ do_test (9, 3, hlen, klen, 0);
+ do_test (9, 3, hlen, klen, 1);
+ do_test (9, 9, hlen, klen, 0);
+ do_test (9, 9, hlen, klen, 1);
+ do_test (9, 15, hlen, klen, 0);
+ do_test (9, 15, hlen, klen, 1);
+
+ do_test (15, 0, hlen, klen, 0);
+ do_test (15, 0, hlen, klen, 1);
+ do_test (15, 3, hlen, klen, 0);
+ do_test (15, 3, hlen, klen, 1);
+ do_test (15, 9, hlen, klen, 0);
+ do_test (15, 9, hlen, klen, 1);
+ do_test (15, 15, hlen, klen, 0);
+ do_test (15, 15, hlen, klen, 1);
+ }
+
+ do_test (0, 0, page_size - 1, 16, 0);
+ do_test (0, 0, page_size - 1, 16, 1);
+
+ return ret;
+}
+
+#include "../test-skeleton.c"
Index: glibc-2.12-2-gc4ccff1/string/test-strncasecmp.c
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/string/test-strncasecmp.c
@@ -0,0 +1,349 @@
+/* Test and measure strncasecmp functions.
+ Copyright (C) 1999, 2002, 2003, 2005, 2010 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+ 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 <ctype.h>
+#define TEST_MAIN
+#include "test-string.h"
+
+typedef int (*proto_t) (const char *, const char *, size_t);
+static int simple_strncasecmp (const char *, const char *, size_t);
+static int stupid_strncasecmp (const char *, const char *, size_t);
+
+IMPL (stupid_strncasecmp, 0)
+IMPL (simple_strncasecmp, 0)
+IMPL (strncasecmp, 1)
+
+static int
+simple_strncasecmp (const char *s1, const char *s2, size_t n)
+{
+ int ret;
+
+ if (n == 0)
+ return 0;
+
+ while ((ret = ((unsigned char) tolower (*s1)
+ - (unsigned char) tolower (*s2))) == 0
+ && *s1++)
+ {
+ if (--n == 0)
+ return 0;
+ ++s2;
+ }
+ return ret;
+}
+
+static int
+stupid_strncasecmp (const char *s1, const char *s2, size_t max)
+{
+ size_t ns1 = strlen (s1) + 1;
+ size_t ns2 = strlen (s2) + 1;
+ size_t n = ns1 < ns2 ? ns1 : ns2;
+ if (n > max)
+ n = max;
+ int ret = 0;
+
+ while (n--)
+ {
+ if ((ret = ((unsigned char) tolower (*s1)
+ - (unsigned char) tolower (*s2))) != 0)
+ break;
+ ++s1;
+ ++s2;
+ }
+ return ret;
+}
+
+static int
+check_result (impl_t *impl, const char *s1, const char *s2, size_t n,
+ int exp_result)
+{
+ int result = CALL (impl, s1, s2, n);
+ if ((exp_result == 0 && result != 0)
+ || (exp_result < 0 && result >= 0)
+ || (exp_result > 0 && result <= 0))
+ {
+ error (0, 0, "Wrong result in function %s %d %d", impl->name,
+ result, exp_result);
+ ret = 1;
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n,
+ int exp_result)
+{
+ if (check_result (impl, s1, s2, n, exp_result) < 0)
+ return;
+
+ if (HP_TIMING_AVAIL)
+ {
+ hp_timing_t start __attribute ((unused));
+ hp_timing_t stop __attribute ((unused));
+ hp_timing_t best_time = ~ (hp_timing_t) 0;
+ size_t i;
+
+ for (i = 0; i < 32; ++i)
+ {
+ HP_TIMING_NOW (start);
+ CALL (impl, s1, s2, n);
+ HP_TIMING_NOW (stop);
+ HP_TIMING_BEST (best_time, start, stop);
+ }
+
+ printf ("\t%zd", (size_t) best_time);
+ }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char,
+ int exp_result)
+{
+ size_t i;
+ char *s1, *s2;
+
+ if (len == 0)
+ return;
+
+ align1 &= 7;
+ if (align1 + len + 1 >= page_size)
+ return;
+
+ align2 &= 7;
+ if (align2 + len + 1 >= page_size)
+ return;
+
+ s1 = (char *) (buf1 + align1);
+ s2 = (char *) (buf2 + align2);
+
+ for (i = 0; i < len; i++)
+ {
+ s1[i] = toupper (1 + 23 * i % max_char);
+ s2[i] = tolower (s1[i]);
+ }
+
+ s1[len] = s2[len] = 0;
+ s1[len + 1] = 23;
+ s2[len + 1] = 24 + exp_result;
+ if ((s2[len - 1] == 'z' && exp_result == -1)
+ || (s2[len - 1] == 'a' && exp_result == 1))
+ s1[len - 1] += exp_result;
+ else
+ s2[len - 1] -= exp_result;
+
+ if (HP_TIMING_AVAIL)
+ printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
+
+ FOR_EACH_IMPL (impl, 0)
+ do_one_test (impl, s1, s2, n, exp_result);
+
+ if (HP_TIMING_AVAIL)
+ putchar ('\n');
+}
+
+static void
+do_random_tests (void)
+{
+ size_t i, j, n, align1, align2, pos, len1, len2;
+ int result;
+ long r;
+ unsigned char *p1 = buf1 + page_size - 512;
+ unsigned char *p2 = buf2 + page_size - 512;
+
+ for (n = 0; n < ITERATIONS; n++)
+ {
+ align1 = random () & 31;
+ if (random () & 1)
+ align2 = random () & 31;
+ else
+ align2 = align1 + (random () & 24);
+ pos = random () & 511;
+ j = align1 > align2 ? align1 : align2;
+ if (pos + j >= 511)
+ pos = 510 - j - (random () & 7);
+ len1 = random () & 511;
+ if (pos >= len1 && (random () & 1))
+ len1 = pos + (random () & 7);
+ if (len1 + j >= 512)
+ len1 = 511 - j - (random () & 7);
+ if (pos >= len1)
+ len2 = len1;
+ else
+ len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0);
+ j = (pos > len2 ? pos : len2) + align1 + 64;
+ if (j > 512)
+ j = 512;
+ for (i = 0; i < j; ++i)
+ {
+ p1[i] = tolower (random () & 255);
+ if (i < len1 + align1 && !p1[i])
+ {
+ p1[i] = tolower (random () & 255);
+ if (!p1[i])
+ p1[i] = tolower (1 + (random () & 127));
+ }
+ }
+ for (i = 0; i < j; ++i)
+ {
+ p2[i] = toupper (random () & 255);
+ if (i < len2 + align2 && !p2[i])
+ {
+ p2[i] = toupper (random () & 255);
+ if (!p2[i])
+ toupper (p2[i] = 1 + (random () & 127));
+ }
+ }
+
+ result = 0;
+ memcpy (p2 + align2, p1 + align1, pos);
+ if (pos < len1)
+ {
+ if (tolower (p2[align2 + pos]) == p1[align1 + pos])
+ {
+ p2[align2 + pos] = toupper (random () & 255);
+ if (tolower (p2[align2 + pos]) == p1[align1 + pos])
+ p2[align2 + pos] = toupper (p1[align1 + pos]
+ + 3 + (random () & 127));
+ }
+
+ if (p1[align1 + pos] < tolower (p2[align2 + pos]))
+ result = -1;
+ else
+ result = 1;
+ }
+ p1[len1 + align1] = 0;
+ p2[len2 + align2] = 0;
+
+ FOR_EACH_IMPL (impl, 1)
+ {
+ r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2),
+ pos + 1 + (random () & 255));
+ /* Test whether on 64-bit architectures where ABI requires
+ callee to promote has the promotion been done. */
+ asm ("" : "=g" (r) : "0" (r));
+ if ((r == 0 && result)
+ || (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);
+ ret = 1;
+ }
+ }
+ }
+}
+
+
+static void
+check1 (void)
+{
+ static char cp [4096+16] __attribute__ ((aligned(4096)));
+ static char gotrel[4096] __attribute__ ((aligned(4096)));
+ char *s1 = cp + 0xffa;
+ char *s2 = gotrel + 0xcbe;
+ int exp_result;
+ size_t n = 6;
+
+ strcpy (s1, "gottpoff");
+ strcpy (s2, "GOTPLT");
+
+ exp_result = simple_strncasecmp (s1, s2, n);
+ FOR_EACH_IMPL (impl, 0)
+ check_result (impl, s1, s2, n, exp_result);
+}
+
+int
+test_main (void)
+{
+ size_t i;
+
+ test_init ();
+
+ check1 ();
+
+ printf ("%23s", "");
+ FOR_EACH_IMPL (impl, 0)
+ printf ("\t%s", impl->name);
+ putchar ('\n');
+
+ for (i = 1; i < 16; ++i)
+ {
+ do_test (i, i, i - 1, i, 127, 0);
+
+ do_test (i, i, i, i, 127, 0);
+ do_test (i, i, i, i, 127, 1);
+ do_test (i, i, i, i, 127, -1);
+
+ do_test (i, i, i + 1, i, 127, 0);
+ do_test (i, i, i + 1, i, 127, 1);
+ do_test (i, i, i + 1, i, 127, -1);
+ }
+
+ for (i = 1; i < 10; ++i)
+ {
+ do_test (0, 0, (2 << i) - 1, 2 << i, 127, 0);
+ do_test (0, 0, 2 << i, 2 << i, 254, 0);
+ do_test (0, 0, (2 << i) + 1, 2 << i, 127, 0);
+
+ do_test (0, 0, (2 << i) + 1, 2 << i, 254, 0);
+
+ do_test (0, 0, 2 << i, 2 << i, 127, 1);
+ do_test (0, 0, (2 << i) + 10, 2 << i, 127, 1);
+
+ do_test (0, 0, 2 << i, 2 << i, 254, 1);
+ do_test (0, 0, (2 << i) + 10, 2 << i, 254, 1);
+
+ do_test (0, 0, 2 << i, 2 << i, 127, -1);
+ do_test (0, 0, (2 << i) + 10, 2 << i, 127, -1);
+
+ do_test (0, 0, 2 << i, 2 << i, 254, -1);
+ do_test (0, 0, (2 << i) + 10, 2 << i, 254, -1);
+ }
+
+ for (i = 1; i < 8; ++i)
+ {
+ do_test (i, 2 * i, (8 << i) - 1, 8 << i, 127, 0);
+ do_test (i, 2 * i, 8 << i, 8 << i, 127, 0);
+ do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 0);
+
+ do_test (2 * i, i, (8 << i) - 1, 8 << i, 254, 0);
+ do_test (2 * i, i, 8 << i, 8 << i, 254, 0);
+ do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 0);
+
+ do_test (i, 2 * i, 8 << i, 8 << i, 127, 1);
+ do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 1);
+
+ do_test (2 * i, i, 8 << i, 8 << i, 254, 1);
+ do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 1);
+
+ do_test (i, 2 * i, 8 << i, 8 << i, 127, -1);
+ do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, -1);
+
+ do_test (2 * i, i, 8 << i, 8 << i, 254, -1);
+ do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, -1);
+ }
+
+ do_random_tests ();
+ return ret;
+}
+
+#include "../test-skeleton.c"
Index: glibc-2.12-2-gc4ccff1/string/test-strnlen.c
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/string/test-strnlen.c
@@ -0,0 +1,197 @@
+/* Test and measure strlen functions.
+ Copyright (C) 1999, 2002, 2003, 2005, 2010 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+ 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. */
+
+#define TEST_MAIN
+#include "test-string.h"
+
+typedef size_t (*proto_t) (const char *, size_t);
+size_t simple_strnlen (const char *, size_t);
+
+IMPL (simple_strnlen, 0)
+IMPL (strnlen, 1)
+
+size_t
+simple_strnlen (const char *s, size_t maxlen)
+{
+ size_t i;
+
+ for (i = 0; i < maxlen && s[i]; ++i);
+ return i;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s, size_t maxlen, size_t exp_len)
+{
+ size_t len = CALL (impl, s, maxlen);
+ if (len != exp_len)
+ {
+ error (0, 0, "Wrong result in function %s %zd %zd", impl->name,
+ len, exp_len);
+ ret = 1;
+ return;
+ }
+
+ if (HP_TIMING_AVAIL)
+ {
+ hp_timing_t start __attribute ((unused));
+ hp_timing_t stop __attribute ((unused));
+ hp_timing_t best_time = ~ (hp_timing_t) 0;
+ size_t i;
+
+ for (i = 0; i < 32; ++i)
+ {
+ HP_TIMING_NOW (start);
+ CALL (impl, s, maxlen);
+ HP_TIMING_NOW (stop);
+ HP_TIMING_BEST (best_time, start, stop);
+ }
+
+ printf ("\t%zd", (size_t) best_time);
+ }
+}
+
+static void
+do_test (size_t align, size_t len, size_t maxlen, int max_char)
+{
+ size_t i;
+
+ align &= 7;
+ if (align + len >= page_size)
+ return;
+
+ for (i = 0; i < len; ++i)
+ buf1[align + i] = 1 + 7 * i % max_char;
+ buf1[align + len] = 0;
+
+ if (HP_TIMING_AVAIL)
+ printf ("Length %4zd, alignment %2zd:", len, align);
+
+ FOR_EACH_IMPL (impl, 0)
+ do_one_test (impl, (char *) (buf1 + align), maxlen, MIN (len, maxlen));
+
+ if (HP_TIMING_AVAIL)
+ putchar ('\n');
+}
+
+static void
+do_random_tests (void)
+{
+ size_t i, j, n, align, len;
+ unsigned char *p = buf1 + page_size - 512;
+
+ for (n = 0; n < ITERATIONS; n++)
+ {
+ align = random () & 15;
+ len = random () & 511;
+ if (len + align > 510)
+ len = 511 - align - (random () & 7);
+ j = len + align + 64;
+ if (j > 512)
+ j = 512;
+
+ for (i = 0; i < j; i++)
+ {
+ if (i == len + align)
+ p[i] = 0;
+ else
+ {
+ p[i] = random () & 255;
+ if (i >= align && i < len + align && !p[i])
+ p[i] = (random () & 127) + 1;
+ }
+ }
+
+ FOR_EACH_IMPL (impl, 1)
+ {
+ if (len > 0
+ && CALL (impl, (char *) (p + align), len - 1) != len - 1)
+ {
+ error (0, 0, "Iteration %zd (limited) - wrong result in function %s (%zd) %zd != %zd, p %p",
+ n, impl->name, align,
+ CALL (impl, (char *) (p + align), len - 1), len - 1, p);
+ ret = 1;
+ }
+ if (CALL (impl, (char *) (p + align), len) != len)
+ {
+ error (0, 0, "Iteration %zd (exact) - wrong result in function %s (%zd) %zd != %zd, p %p",
+ n, impl->name, align,
+ CALL (impl, (char *) (p + align), len), len, p);
+ ret = 1;
+ }
+ if (CALL (impl, (char *) (p + align), len + 1) != len)
+ {
+ error (0, 0, "Iteration %zd (long) - wrong result in function %s (%zd) %zd != %zd, p %p",
+ n, impl->name, align,
+ CALL (impl, (char *) (p + align), len + 1), len, p);
+ ret = 1;
+ }
+ }
+ }
+}
+
+int
+test_main (void)
+{
+ size_t i;
+
+ test_init ();
+
+ printf ("%20s", "");
+ FOR_EACH_IMPL (impl, 0)
+ printf ("\t%s", impl->name);
+ putchar ('\n');
+
+ for (i = 1; i < 8; ++i)
+ {
+ do_test (0, i, i - 1, 127);
+ do_test (0, i, i, 127);
+ do_test (0, i, i + 1, 127);
+ }
+
+ for (i = 1; i < 8; ++i)
+ {
+ do_test (i, i, i - 1, 127);
+ do_test (i, i, i, 127);
+ do_test (i, i, i + 1, 127);
+ }
+
+ for (i = 2; i <= 10; ++i)
+ {
+ do_test (0, 1 << i, 5000, 127);
+ do_test (1, 1 << i, 5000, 127);
+ }
+
+ for (i = 1; i < 8; ++i)
+ do_test (0, i, 5000, 255);
+
+ for (i = 1; i < 8; ++i)
+ do_test (i, i, 5000, 255);
+
+ for (i = 2; i <= 10; ++i)
+ {
+ do_test (0, 1 << i, 5000, 255);
+ do_test (1, 1 << i, 5000, 255);
+ }
+
+ do_random_tests ();
+ return ret;
+}
+
+#include "../test-skeleton.c"
Index: glibc-2.12-2-gc4ccff1/string/test-strstr.c
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/string/test-strstr.c
@@ -0,0 +1,194 @@
+/* Test and measure strstr functions.
+ Copyright (C) 2010 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2010.
+
+ 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. */
+
+#define TEST_MAIN
+#include "test-string.h"
+
+
+#define STRSTR simple_strstr
+#include "strstr.c"
+
+
+static char *
+stupid_strstr (const char *s1, const char *s2)
+{
+ ssize_t s1len = strlen (s1);
+ ssize_t s2len = strlen (s2);
+
+ if (s2len > s1len)
+ return NULL;
+
+ for (ssize_t i = 0; i <= s1len - s2len; ++i)
+ {
+ size_t j;
+ for (j = 0; j < s2len; ++j)
+ if (s1[i + j] != s2[j])
+ break;
+ if (j == s2len)
+ return (char *) s1 + i;
+ }
+
+ return NULL;
+}
+
+
+typedef char *(*proto_t) (const char *, const char *);
+
+IMPL (stupid_strstr, 0)
+IMPL (simple_strstr, 0)
+IMPL (strstr, 1)
+
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+{
+ char *result = CALL (impl, s1, s2);
+ if (result != exp_result)
+ {
+ error (0, 0, "Wrong result in function %s %s %s", impl->name,
+ result, exp_result);
+ ret = 1;
+ return;
+ }
+
+ if (HP_TIMING_AVAIL)
+ {
+ hp_timing_t start __attribute ((unused));
+ hp_timing_t stop __attribute ((unused));
+ hp_timing_t best_time = ~(hp_timing_t) 0;
+ size_t i;
+
+ for (i = 0; i < 32; ++i)
+ {
+ HP_TIMING_NOW (start);
+ CALL (impl, s1, s2);
+ HP_TIMING_NOW (stop);
+ HP_TIMING_BEST (best_time, start, stop);
+ }
+
+ printf ("\t%zd", (size_t) best_time);
+ }
+}
+
+
+static void
+do_test (size_t align1, size_t align2, size_t len1, size_t len2,
+ int fail)
+{
+ char *s1 = (char *) (buf1 + align1);
+ char *s2 = (char *) (buf2 + align2);
+
+ static const char d[] = "1234567890abcdef";
+#define dl (sizeof (d) - 1)
+ char *ss2 = s2;
+ for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0)
+ {
+ size_t t = l > dl ? dl : l;
+ ss2 = mempcpy (ss2, d, t);
+ }
+ s2[len2] = '\0';
+
+ if (fail)
+ {
+ char *ss1 = s1;
+ for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0)
+ {
+ size_t t = l > dl ? dl : l;
+ memcpy (ss1, d, t);
+ ++ss1[len2 > 7 ? 7 : len2 - 1];
+ ss1 += t;
+ }
+ }
+ else
+ {
+ memset (s1, '0', len1);
+ memcpy (s1 + len1 - len2, s2, len2);
+ }
+ s1[len1] = '\0';
+
+ if (HP_TIMING_AVAIL)
+ printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:",
+ len1, len2, align1, align2, fail ? "fail" : "found");
+
+ FOR_EACH_IMPL (impl, 0)
+ do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2);
+
+ if (HP_TIMING_AVAIL)
+ putchar ('\n');
+}
+
+
+static int
+test_main (void)
+{
+ test_init ();
+
+ printf ("%23s", "");
+ FOR_EACH_IMPL (impl, 0)
+ printf ("\t%s", impl->name);
+ putchar ('\n');
+
+ for (size_t klen = 2; klen < 32; ++klen)
+ for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen)
+ {
+ do_test (0, 0, hlen, klen, 0);
+ do_test (0, 0, hlen, klen, 1);
+ do_test (0, 3, hlen, klen, 0);
+ do_test (0, 3, hlen, klen, 1);
+ do_test (0, 9, hlen, klen, 0);
+ do_test (0, 9, hlen, klen, 1);
+ do_test (0, 15, hlen, klen, 0);
+ do_test (0, 15, hlen, klen, 1);
+
+ do_test (3, 0, hlen, klen, 0);
+ do_test (3, 0, hlen, klen, 1);
+ do_test (3, 3, hlen, klen, 0);
+ do_test (3, 3, hlen, klen, 1);
+ do_test (3, 9, hlen, klen, 0);
+ do_test (3, 9, hlen, klen, 1);
+ do_test (3, 15, hlen, klen, 0);
+ do_test (3, 15, hlen, klen, 1);
+
+ do_test (9, 0, hlen, klen, 0);
+ do_test (9, 0, hlen, klen, 1);
+ do_test (9, 3, hlen, klen, 0);
+ do_test (9, 3, hlen, klen, 1);
+ do_test (9, 9, hlen, klen, 0);
+ do_test (9, 9, hlen, klen, 1);
+ do_test (9, 15, hlen, klen, 0);
+ do_test (9, 15, hlen, klen, 1);
+
+ do_test (15, 0, hlen, klen, 0);
+ do_test (15, 0, hlen, klen, 1);
+ do_test (15, 3, hlen, klen, 0);
+ do_test (15, 3, hlen, klen, 1);
+ do_test (15, 9, hlen, klen, 0);
+ do_test (15, 9, hlen, klen, 1);
+ do_test (15, 15, hlen, klen, 0);
+ do_test (15, 15, hlen, klen, 1);
+ }
+
+ do_test (0, 0, page_size - 1, 16, 0);
+ do_test (0, 0, page_size - 1, 16, 1);
+
+ return ret;
+}
+
+#include "../test-skeleton.c"
Index: glibc-2.12-2-gc4ccff1/string/tester.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/string/tester.c
+++ glibc-2.12-2-gc4ccff1/string/tester.c
@@ -441,20 +441,21 @@ test_strnlen (void)
check (strnlen ("", 10) == 0, 1); /* Empty. */
check (strnlen ("a", 10) == 1, 2); /* Single char. */
check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
- check (strnlen ("foo", (size_t)-1) == 3, 4); /* limits of n. */
+ check (strnlen ("foo", (size_t) -1) == 3, 4); /* limits of n. */
+ check (strnlen ("abcd", 0) == 0, 5); /* Restricted. */
+ check (strnlen ("abcd", 1) == 1, 6); /* Restricted. */
+ check (strnlen ("abcd", 2) == 2, 7); /* Restricted. */
+ check (strnlen ("abcd", 3) == 3, 8); /* Restricted. */
+ check (strnlen ("abcd", 4) == 4, 9); /* Restricted. */
- {
- char buf[4096];
- int i;
- char *p;
- for (i=0; i < 0x100; i++)
- {
- p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
- strcpy (p, "OK");
- strcpy (p+3, "BAD/WRONG");
- check (strnlen (p, 100) == 2, 5+i);
- }
- }
+ char buf[4096];
+ for (int i = 0; i < 0x100; ++i)
+ {
+ char *p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
+ strcpy (p, "OK");
+ strcpy (p + 3, "BAD/WRONG");
+ check (strnlen (p, 100) == 2, 10 + i);
+ }
}
static void
Index: glibc-2.12-2-gc4ccff1/string/tst-strlen.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/string/tst-strlen.c
+++ glibc-2.12-2-gc4ccff1/string/tst-strlen.c
@@ -31,11 +31,21 @@ main(int argc, char *argv[])
buf[words * 4 + 3] = (last & 8) != 0 ? 'e' : '\0';
buf[words * 4 + 4] = '\0';
- if (strlen (buf) != words * 4 + lens[last]
- || strnlen (buf, -1) != words * 4 + lens[last])
+ if (strlen (buf) != words * 4 + lens[last])
{
- printf ("failed for base=%Zu, words=%Zu, and last=%Zu\n",
- base, words, last);
+ printf ("\
+strlen failed for base=%Zu, words=%Zu, and last=%Zu (is %zd, expected %zd)\n",
+ base, words, last,
+ strlen (buf), words * 4 + lens[last]);
+ return 1;
+ }
+
+ if (strnlen (buf, -1) != words * 4 + lens[last])
+ {
+ printf ("\
+strnlen failed for base=%Zu, words=%Zu, and last=%Zu (is %zd, expected %zd)\n",
+ base, words, last,
+ strnlen (buf, -1), words * 4 + lens[last]);
return 1;
}
}
Index: glibc-2.12-2-gc4ccff1/sysdeps/i386/i686/multiarch/Makefile
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/i386/i686/multiarch/Makefile
+++ glibc-2.12-2-gc4ccff1/sysdeps/i386/i686/multiarch/Makefile
@@ -9,7 +9,7 @@ sysdep_routines += bzero-sse2 memset-sse
memmove-ssse3-rep bcopy-ssse3 bcopy-ssse3-rep \
memset-sse2-rep bzero-sse2-rep strcmp-ssse3 \
strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \
- memcmp-ssse3 memcmp-sse4
+ memcmp-ssse3 memcmp-sse4 strcasestr-nonascii
ifeq (yes,$(config-cflags-sse4))
sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c
CFLAGS-strcspn-c.c += -msse4
@@ -17,6 +17,7 @@ CFLAGS-strpbrk-c.c += -msse4
CFLAGS-strspn-c.c += -msse4
CFLAGS-strstr.c += -msse4
CFLAGS-strcasestr.c += -msse4
+CFLAGS-strcasestr-nonascii.c += -msse4
endif
endif
Index: glibc-2.12-2-gc4ccff1/sysdeps/i386/i686/multiarch/strcasestr-nonascii.c
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/i386/i686/multiarch/strcasestr-nonascii.c
@@ -0,0 +1,2 @@
+#include <nmmintrin.h>
+#include <sysdeps/x86_64/multiarch/strcasestr-nonascii.c>
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/Makefile
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/x86_64/Makefile
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/Makefile
@@ -12,7 +12,8 @@ sysdep_routines += _mcount
endif
ifeq ($(subdir),string)
-sysdep_routines += cacheinfo
+sysdep_routines += cacheinfo strcasecmp_l-nonascii strncase_l-nonascii
+gen-as-const-headers += locale-defines.sym
endif
ifeq ($(subdir),elf)
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/locale-defines.sym
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/locale-defines.sym
@@ -0,0 +1,11 @@
+#include <locale/localeinfo.h>
+#include <langinfo.h>
+#include <stddef.h>
+
+--
+
+LOCALE_T___LOCALES offsetof (struct __locale_struct, __locales)
+LC_CTYPE
+_NL_CTYPE_NONASCII_CASE
+LOCALE_DATA_VALUES offsetof (struct __locale_data, values)
+SIZEOF_VALUES sizeof (((struct __locale_data *) 0)->values[0])
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/Makefile
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/x86_64/multiarch/Makefile
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/Makefile
@@ -5,7 +5,9 @@ endif
ifeq ($(subdir),string)
sysdep_routines += stpncpy-c strncpy-c strcmp-ssse3 strncmp-ssse3 \
- strend-sse4 memcmp-sse4
+ strend-sse4 memcmp-sse4 \
+ strcasestr-nonascii strcasecmp_l-ssse3 \
+ strncase_l-ssse3
ifeq (yes,$(config-cflags-sse4))
sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c
CFLAGS-strcspn-c.c += -msse4
@@ -13,5 +15,6 @@ CFLAGS-strpbrk-c.c += -msse4
CFLAGS-strspn-c.c += -msse4
CFLAGS-strstr.c += -msse4
CFLAGS-strcasestr.c += -msse4
+CFLAGS-strcasestr-nonascii.c += -msse4
endif
endif
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strcasecmp_l-ssse3.S
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strcasecmp_l-ssse3.S
@@ -0,0 +1,6 @@
+#define USE_SSSE3 1
+#define USE_AS_STRCASECMP_L
+#define NO_NOLOCALE_ALIAS
+#define STRCMP __strcasecmp_l_ssse3
+#define __strcasecmp __strcasecmp_ssse3
+#include "../strcmp.S"
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strcasecmp_l.S
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strcasecmp_l.S
@@ -0,0 +1,6 @@
+#define STRCMP __strcasecmp_l
+#define USE_AS_STRCASECMP_L
+#include "strcmp.S"
+
+weak_alias (__strcasecmp_l, strcasecmp_l)
+libc_hidden_def (strcasecmp_l)
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strcasestr-nonascii.c
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strcasestr-nonascii.c
@@ -0,0 +1,50 @@
+/* strstr with SSE4.2 intrinsics
+ Copyright (C) 2010 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 <ctype.h>
+
+
+/* Similar to __m128i_strloadu. Convert to lower case for none-POSIX/C
+ locale. */
+static inline __m128i
+__m128i_strloadu_tolower (const unsigned char *p)
+{
+ union
+ {
+ char b[16];
+ __m128i x;
+ } u;
+
+ for (int i = 0; i < 16; ++i)
+ if (p[i] == 0)
+ {
+ u.b[i] = 0;
+ break;
+ }
+ else
+ u.b[i] = tolower (p[i]);
+
+ return u.x;
+}
+
+
+#define STRCASESTR_NONASCII
+#define USE_AS_STRCASESTR
+#define STRSTR_SSE42 __strcasestr_sse42_nonascii
+#include "strstr.c"
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strcasestr.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/x86_64/multiarch/strcasestr.c
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strcasestr.c
@@ -1,3 +1,7 @@
+extern char *__strcasestr_sse42_nonascii (const unsigned char *s1,
+ const unsigned char *s2)
+ attribute_hidden;
+
#define USE_AS_STRCASESTR
#define STRSTR_SSE42 __strcasestr_sse42
#include "strstr.c"
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strcmp.S
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/x86_64/multiarch/strcmp.S
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strcmp.S
@@ -24,7 +24,7 @@
#ifdef USE_AS_STRNCMP
/* Since the counter, %r11, is unsigned, we branch to strcmp_exitz
if the new counter > the old one or is 0. */
-#define UPDATE_STRNCMP_COUNTER \
+# define UPDATE_STRNCMP_COUNTER \
/* calculate left number to compare */ \
lea -16(%rcx, %r11), %r9; \
cmp %r9, %r11; \
@@ -33,23 +33,50 @@
je LABEL(strcmp_exitz_sse4_2); \
mov %r9, %r11
-#define STRCMP_SSE42 __strncmp_sse42
-#define STRCMP_SSSE3 __strncmp_ssse3
-#define STRCMP_SSE2 __strncmp_sse2
-#define __GI_STRCMP __GI_strncmp
+# define STRCMP_SSE42 __strncmp_sse42
+# define STRCMP_SSSE3 __strncmp_ssse3
+# define STRCMP_SSE2 __strncmp_sse2
+# define __GI_STRCMP __GI_strncmp
+#elif defined USE_AS_STRCASECMP_L
+# include "locale-defines.h"
+
+# define UPDATE_STRNCMP_COUNTER
+
+# define STRCMP_SSE42 __strcasecmp_l_sse42
+# define STRCMP_SSSE3 __strcasecmp_l_ssse3
+# define STRCMP_SSE2 __strcasecmp_l_sse2
+# define __GI_STRCMP __GI___strcasecmp_l
+#elif defined USE_AS_STRNCASECMP_L
+# include "locale-defines.h"
+
+/* Since the counter, %r11, is unsigned, we branch to strcmp_exitz
+ if the new counter > the old one or is 0. */
+# define UPDATE_STRNCMP_COUNTER \
+ /* calculate left number to compare */ \
+ lea -16(%rcx, %r11), %r9; \
+ cmp %r9, %r11; \
+ jb LABEL(strcmp_exitz_sse4_2); \
+ test %r9, %r9; \
+ je LABEL(strcmp_exitz_sse4_2); \
+ mov %r9, %r11
+
+# define STRCMP_SSE42 __strncasecmp_l_sse42
+# define STRCMP_SSSE3 __strncasecmp_l_ssse3
+# define STRCMP_SSE2 __strncasecmp_l_sse2
+# define __GI_STRCMP __GI___strncasecmp_l
#else
-#define UPDATE_STRNCMP_COUNTER
-#ifndef STRCMP
-#define STRCMP strcmp
-#define STRCMP_SSE42 __strcmp_sse42
-#define STRCMP_SSSE3 __strcmp_ssse3
-#define STRCMP_SSE2 __strcmp_sse2
-#define __GI_STRCMP __GI_strcmp
-#endif
+# define UPDATE_STRNCMP_COUNTER
+# ifndef STRCMP
+# define STRCMP strcmp
+# define STRCMP_SSE42 __strcmp_sse42
+# define STRCMP_SSSE3 __strcmp_ssse3
+# define STRCMP_SSE2 __strcmp_sse2
+# define __GI_STRCMP __GI_strcmp
+# endif
#endif
#ifndef LABEL
-#define LABEL(l) L(l)
+# define LABEL(l) L(l)
#endif
/* Define multiple versions only for the definition in libc. Don't
@@ -73,6 +100,43 @@ ENTRY(STRCMP)
2: ret
END(STRCMP)
+# ifdef USE_AS_STRCASECMP_L
+ENTRY(__strcasecmp)
+ .type __strcasecmp, @gnu_indirect_function
+ cmpl $0, __cpu_features+KIND_OFFSET(%rip)
+ jne 1f
+ call __init_cpu_features
+1:
+ leaq __strcasecmp_sse42(%rip), %rax
+ testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip)
+ jnz 2f
+ leaq __strcasecmp_ssse3(%rip), %rax
+ testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip)
+ jnz 2f
+ leaq __strcasecmp_sse2(%rip), %rax
+2: ret
+END(__strcasecmp)
+weak_alias (__strcasecmp, strcasecmp)
+# endif
+# ifdef USE_AS_STRNCASECMP_L
+ENTRY(__strncasecmp)
+ .type __strncasecmp, @gnu_indirect_function
+ cmpl $0, __cpu_features+KIND_OFFSET(%rip)
+ jne 1f
+ call __init_cpu_features
+1:
+ leaq __strncasecmp_sse42(%rip), %rax
+ testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip)
+ jnz 2f
+ leaq __strncasecmp_ssse3(%rip), %rax
+ testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip)
+ jnz 2f
+ leaq __strncasecmp_sse2(%rip), %rax
+2: ret
+END(__strncasecmp)
+weak_alias (__strncasecmp, strncasecmp)
+# endif
+
/* We use 0x1a:
_SIDD_SBYTE_OPS
| _SIDD_CMP_EQUAL_EACH
@@ -101,8 +165,31 @@ END(STRCMP)
/* Put all SSE 4.2 functions together. */
.section .text.sse4.2,"ax",@progbits
- .align 16
+ .align 16
.type STRCMP_SSE42, @function
+# ifdef USE_AS_STRCASECMP_L
+ENTRY (__strcasecmp_sse42)
+ movq __libc_tsd_LOCALE@gottpoff(%rip),%rax
+ movq %fs:(%rax),%rdx
+
+ // XXX 5 byte should be before the function
+ /* 5-byte NOP. */
+ .byte 0x0f,0x1f,0x44,0x00,0x00
+END (__strcasecmp_sse42)
+ /* FALLTHROUGH to strcasecmp_l. */
+# endif
+# ifdef USE_AS_STRNCASECMP_L
+ENTRY (__strncasecmp_sse42)
+ movq __libc_tsd_LOCALE@gottpoff(%rip),%rax
+ movq %fs:(%rax),%rcx
+
+ // XXX 5 byte should be before the function
+ /* 5-byte NOP. */
+ .byte 0x0f,0x1f,0x44,0x00,0x00
+END (__strncasecmp_sse42)
+ /* FALLTHROUGH to strncasecmp_l. */
+# endif
+
STRCMP_SSE42:
cfi_startproc
CALL_MCOUNT
@@ -110,24 +197,87 @@ STRCMP_SSE42:
/*
* This implementation uses SSE to compare up to 16 bytes at a time.
*/
-#ifdef USE_AS_STRNCMP
+# ifdef USE_AS_STRCASECMP_L
+ /* We have to fall back on the C implementation for locales
+ with encodings not matching ASCII for single bytes. */
+# if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
+ movq LOCALE_T___LOCALES+LC_CTYPE*8(%rdx), %rax
+# else
+ movq (%rdx), %rax
+# endif
+ testl $0, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%rax)
+ jne __strcasecmp_l_nonascii
+# endif
+# ifdef USE_AS_STRNCASECMP_L
+ /* We have to fall back on the C implementation for locales
+ with encodings not matching ASCII for single bytes. */
+# if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
+ movq LOCALE_T___LOCALES+LC_CTYPE*8(%rcx), %rax
+# else
+ movq (%rcx), %rax
+# endif
+ testl $0, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%rax)
+ jne __strncasecmp_l_nonascii
+# endif
+
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
test %rdx, %rdx
je LABEL(strcmp_exitz_sse4_2)
cmp $1, %rdx
je LABEL(Byte0_sse4_2)
mov %rdx, %r11
-#endif
+# endif
mov %esi, %ecx
mov %edi, %eax
/* Use 64bit AND here to avoid long NOP padding. */
and $0x3f, %rcx /* rsi alignment in cache line */
and $0x3f, %rax /* rdi alignment in cache line */
+# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
+ .section .rodata.cst16,"aM",@progbits,16
+ .align 16
+.Lbelowupper_sse4:
+ .quad 0x4040404040404040
+ .quad 0x4040404040404040
+.Ltopupper_sse4:
+ .quad 0x5b5b5b5b5b5b5b5b
+ .quad 0x5b5b5b5b5b5b5b5b
+.Ltouppermask_sse4:
+ .quad 0x2020202020202020
+ .quad 0x2020202020202020
+ .previous
+ movdqa .Lbelowupper_sse4(%rip), %xmm4
+# define UCLOW_reg %xmm4
+ movdqa .Ltopupper_sse4(%rip), %xmm5
+# define UCHIGH_reg %xmm5
+ movdqa .Ltouppermask_sse4(%rip), %xmm6
+# define LCQWORD_reg %xmm6
+# endif
cmp $0x30, %ecx
ja LABEL(crosscache_sse4_2)/* rsi: 16-byte load will cross cache line */
cmp $0x30, %eax
ja LABEL(crosscache_sse4_2)/* rdi: 16-byte load will cross cache line */
movdqu (%rdi), %xmm1
movdqu (%rsi), %xmm2
+# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
+# define TOLOWER(reg1, reg2) \
+ movdqa reg1, %xmm7; \
+ movdqa UCHIGH_reg, %xmm8; \
+ movdqa reg2, %xmm9; \
+ movdqa UCHIGH_reg, %xmm10; \
+ pcmpgtb UCLOW_reg, %xmm7; \
+ pcmpgtb reg1, %xmm8; \
+ pcmpgtb UCLOW_reg, %xmm9; \
+ pcmpgtb reg2, %xmm10; \
+ pand %xmm8, %xmm7; \
+ pand %xmm10, %xmm9; \
+ pand LCQWORD_reg, %xmm7; \
+ pand LCQWORD_reg, %xmm9; \
+ por %xmm7, reg1; \
+ por %xmm9, reg2
+ TOLOWER (%xmm1, %xmm2)
+# else
+# define TOLOWER(reg1, reg2)
+# endif
pxor %xmm0, %xmm0 /* clear %xmm0 for null char checks */
pcmpeqb %xmm1, %xmm0 /* Any null chars? */
pcmpeqb %xmm2, %xmm1 /* compare first 16 bytes for equality */
@@ -135,10 +285,10 @@ STRCMP_SSE42:
pmovmskb %xmm1, %edx
sub $0xffff, %edx /* if first 16 bytes are same, edx == 0xffff */
jnz LABEL(less16bytes_sse4_2)/* If not, find different value or null char */
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)/* finish comparision */
-#endif
+# endif
add $16, %rsi /* prepare to search next 16 bytes */
add $16, %rdi /* prepare to search next 16 bytes */
@@ -180,7 +330,13 @@ LABEL(ashr_0_sse4_2):
movdqa (%rsi), %xmm1
pxor %xmm0, %xmm0 /* clear %xmm0 for null char check */
pcmpeqb %xmm1, %xmm0 /* Any null chars? */
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpeqb (%rdi), %xmm1 /* compare 16 bytes for equality */
+# else
+ movdqa (%rdi), %xmm2
+ TOLOWER (%xmm1, %xmm2)
+ pcmpeqb %xmm2, %xmm1 /* compare 16 bytes for equality */
+# endif
psubb %xmm0, %xmm1 /* packed sub of comparison results*/
pmovmskb %xmm1, %r9d
shr %cl, %edx /* adjust 0xffff for offset */
@@ -204,44 +360,60 @@ LABEL(ashr_0_sse4_2):
.p2align 4
LABEL(ashr_0_use_sse4_2):
movdqa (%rdi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
lea 16(%rdx), %rdx
jbe LABEL(ashr_0_use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
movdqa (%rdi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
lea 16(%rdx), %rdx
jbe LABEL(ashr_0_use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
jmp LABEL(ashr_0_use_sse4_2)
.p2align 4
LABEL(ashr_0_use_sse4_2_exit):
jnc LABEL(strcmp_exitz_sse4_2)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub %rcx, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
lea -16(%rdx, %rcx), %rcx
movzbl (%rdi, %rcx), %eax
movzbl (%rsi, %rcx), %edx
+# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
+ leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rcx
+ movl (%rcx,%rax,4), %eax
+ movl (%rcx,%rdx,4), %edx
+# endif
sub %edx, %eax
ret
-
/*
* The following cases will be handled by ashr_1
- * rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
+ * rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
* n(15) n -15 0(15 +(n-15) - n) ashr_1
*/
.p2align 4
@@ -251,6 +423,7 @@ LABEL(ashr_1_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0 /* Any null chars? */
pslldq $15, %xmm2 /* shift first string to align with second */
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2 /* compare 16 bytes for equality */
psubb %xmm0, %xmm2 /* packed sub of comparison results*/
pmovmskb %xmm2, %r9d
@@ -281,12 +454,18 @@ LABEL(loop_ashr_1_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $1, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -294,12 +473,18 @@ LABEL(loop_ashr_1_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $1, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_1_use_sse4_2)
@@ -309,10 +494,10 @@ LABEL(nibble_ashr_1_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $1, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $14, %ecx
ja LABEL(loop_ashr_1_use_sse4_2)
@@ -320,7 +505,7 @@ LABEL(nibble_ashr_1_use_sse4_2):
/*
* The following cases will be handled by ashr_2
- * rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
+ * rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
* n(14~15) n -14 1(15 +(n-14) - n) ashr_2
*/
.p2align 4
@@ -330,6 +515,7 @@ LABEL(ashr_2_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $14, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -360,12 +546,18 @@ LABEL(loop_ashr_2_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $2, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -373,12 +565,18 @@ LABEL(loop_ashr_2_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $2, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_2_use_sse4_2)
@@ -388,10 +586,10 @@ LABEL(nibble_ashr_2_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $2, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $13, %ecx
ja LABEL(loop_ashr_2_use_sse4_2)
@@ -409,6 +607,7 @@ LABEL(ashr_3_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $13, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -439,12 +638,18 @@ LABEL(loop_ashr_3_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $3, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -452,12 +657,18 @@ LABEL(loop_ashr_3_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $3, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_3_use_sse4_2)
@@ -467,10 +678,10 @@ LABEL(nibble_ashr_3_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $3, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $12, %ecx
ja LABEL(loop_ashr_3_use_sse4_2)
@@ -488,6 +699,7 @@ LABEL(ashr_4_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $12, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -519,12 +731,18 @@ LABEL(loop_ashr_4_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $4, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -532,12 +750,18 @@ LABEL(loop_ashr_4_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $4, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_4_use_sse4_2)
@@ -547,10 +771,10 @@ LABEL(nibble_ashr_4_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $4, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $11, %ecx
ja LABEL(loop_ashr_4_use_sse4_2)
@@ -559,7 +783,7 @@ LABEL(nibble_ashr_4_use_sse4_2):
/*
* The following cases will be handled by ashr_5
* rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
- * n(11~15) n - 11 4(15 +(n-11) - n) ashr_5
+ * n(11~15) n - 11 4(15 +(n-11) - n) ashr_5
*/
.p2align 4
LABEL(ashr_5_sse4_2):
@@ -568,6 +792,7 @@ LABEL(ashr_5_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $11, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -599,12 +824,18 @@ LABEL(loop_ashr_5_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $5, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -613,12 +844,18 @@ LABEL(loop_ashr_5_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $5, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_5_use_sse4_2)
@@ -628,10 +865,10 @@ LABEL(nibble_ashr_5_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $5, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $10, %ecx
ja LABEL(loop_ashr_5_use_sse4_2)
@@ -640,7 +877,7 @@ LABEL(nibble_ashr_5_use_sse4_2):
/*
* The following cases will be handled by ashr_6
* rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
- * n(10~15) n - 10 5(15 +(n-10) - n) ashr_6
+ * n(10~15) n - 10 5(15 +(n-10) - n) ashr_6
*/
.p2align 4
LABEL(ashr_6_sse4_2):
@@ -649,6 +886,7 @@ LABEL(ashr_6_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $10, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -680,12 +918,18 @@ LABEL(loop_ashr_6_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $6, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -693,12 +937,18 @@ LABEL(loop_ashr_6_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $6, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_6_use_sse4_2)
@@ -708,10 +958,10 @@ LABEL(nibble_ashr_6_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $6, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $9, %ecx
ja LABEL(loop_ashr_6_use_sse4_2)
@@ -720,7 +970,7 @@ LABEL(nibble_ashr_6_use_sse4_2):
/*
* The following cases will be handled by ashr_7
* rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
- * n(9~15) n - 9 6(15 +(n - 9) - n) ashr_7
+ * n(9~15) n - 9 6(15 +(n - 9) - n) ashr_7
*/
.p2align 4
LABEL(ashr_7_sse4_2):
@@ -729,6 +979,7 @@ LABEL(ashr_7_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $9, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -760,12 +1011,18 @@ LABEL(loop_ashr_7_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $7, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -773,12 +1030,18 @@ LABEL(loop_ashr_7_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $7, -16(%rdi, %rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_7_use_sse4_2)
@@ -788,10 +1051,10 @@ LABEL(nibble_ashr_7_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $7, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $8, %ecx
ja LABEL(loop_ashr_7_use_sse4_2)
@@ -800,7 +1063,7 @@ LABEL(nibble_ashr_7_use_sse4_2):
/*
* The following cases will be handled by ashr_8
* rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
- * n(8~15) n - 8 7(15 +(n - 8) - n) ashr_8
+ * n(8~15) n - 8 7(15 +(n - 8) - n) ashr_8
*/
.p2align 4
LABEL(ashr_8_sse4_2):
@@ -809,6 +1072,7 @@ LABEL(ashr_8_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $8, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -840,12 +1104,18 @@ LABEL(loop_ashr_8_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $8, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -853,12 +1123,18 @@ LABEL(loop_ashr_8_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $8, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_8_use_sse4_2)
@@ -868,10 +1144,10 @@ LABEL(nibble_ashr_8_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $8, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $7, %ecx
ja LABEL(loop_ashr_8_use_sse4_2)
@@ -880,7 +1156,7 @@ LABEL(nibble_ashr_8_use_sse4_2):
/*
* The following cases will be handled by ashr_9
* rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
- * n(7~15) n - 7 8(15 +(n - 7) - n) ashr_9
+ * n(7~15) n - 7 8(15 +(n - 7) - n) ashr_9
*/
.p2align 4
LABEL(ashr_9_sse4_2):
@@ -889,6 +1165,7 @@ LABEL(ashr_9_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $7, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -921,12 +1198,18 @@ LABEL(loop_ashr_9_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $9, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -934,12 +1217,18 @@ LABEL(loop_ashr_9_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $9, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_9_use_sse4_2)
@@ -949,10 +1238,10 @@ LABEL(nibble_ashr_9_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $9, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $6, %ecx
ja LABEL(loop_ashr_9_use_sse4_2)
@@ -961,7 +1250,7 @@ LABEL(nibble_ashr_9_use_sse4_2):
/*
* The following cases will be handled by ashr_10
* rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
- * n(6~15) n - 6 9(15 +(n - 6) - n) ashr_10
+ * n(6~15) n - 6 9(15 +(n - 6) - n) ashr_10
*/
.p2align 4
LABEL(ashr_10_sse4_2):
@@ -970,6 +1259,7 @@ LABEL(ashr_10_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $6, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1001,12 +1291,18 @@ LABEL(loop_ashr_10_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $10, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -1014,12 +1310,18 @@ LABEL(loop_ashr_10_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $10, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_10_use_sse4_2)
@@ -1029,10 +1331,10 @@ LABEL(nibble_ashr_10_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $10, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $5, %ecx
ja LABEL(loop_ashr_10_use_sse4_2)
@@ -1041,7 +1343,7 @@ LABEL(nibble_ashr_10_use_sse4_2):
/*
* The following cases will be handled by ashr_11
* rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
- * n(5~15) n - 5 10(15 +(n - 5) - n) ashr_11
+ * n(5~15) n - 5 10(15 +(n - 5) - n) ashr_11
*/
.p2align 4
LABEL(ashr_11_sse4_2):
@@ -1050,6 +1352,7 @@ LABEL(ashr_11_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $5, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1081,12 +1384,18 @@ LABEL(loop_ashr_11_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $11, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -1094,12 +1403,18 @@ LABEL(loop_ashr_11_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $11, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_11_use_sse4_2)
@@ -1109,10 +1424,10 @@ LABEL(nibble_ashr_11_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $11, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $4, %ecx
ja LABEL(loop_ashr_11_use_sse4_2)
@@ -1121,7 +1436,7 @@ LABEL(nibble_ashr_11_use_sse4_2):
/*
* The following cases will be handled by ashr_12
* rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
- * n(4~15) n - 4 11(15 +(n - 4) - n) ashr_12
+ * n(4~15) n - 4 11(15 +(n - 4) - n) ashr_12
*/
.p2align 4
LABEL(ashr_12_sse4_2):
@@ -1130,6 +1445,7 @@ LABEL(ashr_12_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $4, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1161,12 +1477,18 @@ LABEL(loop_ashr_12_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $12, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -1174,12 +1496,18 @@ LABEL(loop_ashr_12_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $12, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_12_use_sse4_2)
@@ -1189,10 +1517,10 @@ LABEL(nibble_ashr_12_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $12, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $3, %ecx
ja LABEL(loop_ashr_12_use_sse4_2)
@@ -1201,7 +1529,7 @@ LABEL(nibble_ashr_12_use_sse4_2):
/*
* The following cases will be handled by ashr_13
* rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
- * n(3~15) n - 3 12(15 +(n - 3) - n) ashr_13
+ * n(3~15) n - 3 12(15 +(n - 3) - n) ashr_13
*/
.p2align 4
LABEL(ashr_13_sse4_2):
@@ -1210,6 +1538,7 @@ LABEL(ashr_13_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $3, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1242,12 +1571,18 @@ LABEL(loop_ashr_13_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $13, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -1255,12 +1590,18 @@ LABEL(loop_ashr_13_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $13, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_13_use_sse4_2)
@@ -1270,10 +1611,10 @@ LABEL(nibble_ashr_13_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $13, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $2, %ecx
ja LABEL(loop_ashr_13_use_sse4_2)
@@ -1282,7 +1623,7 @@ LABEL(nibble_ashr_13_use_sse4_2):
/*
* The following cases will be handled by ashr_14
* rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
- * n(2~15) n - 2 13(15 +(n - 2) - n) ashr_14
+ * n(2~15) n - 2 13(15 +(n - 2) - n) ashr_14
*/
.p2align 4
LABEL(ashr_14_sse4_2):
@@ -1291,6 +1632,7 @@ LABEL(ashr_14_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $2, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1323,12 +1665,18 @@ LABEL(loop_ashr_14_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $14, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -1336,12 +1684,18 @@ LABEL(loop_ashr_14_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $14, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_14_use_sse4_2)
@@ -1351,10 +1705,10 @@ LABEL(nibble_ashr_14_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $14, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $1, %ecx
ja LABEL(loop_ashr_14_use_sse4_2)
@@ -1363,7 +1717,7 @@ LABEL(nibble_ashr_14_use_sse4_2):
/*
* The following cases will be handled by ashr_15
* rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
- * n(1~15) n - 1 14(15 +(n - 1) - n) ashr_15
+ * n(1~15) n - 1 14(15 +(n - 1) - n) ashr_15
*/
.p2align 4
LABEL(ashr_15_sse4_2):
@@ -1372,6 +1726,7 @@ LABEL(ashr_15_sse4_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $1, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1406,12 +1761,18 @@ LABEL(loop_ashr_15_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $15, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
add $16, %r10
@@ -1419,12 +1780,18 @@ LABEL(loop_ashr_15_use_sse4_2):
movdqa (%rdi, %rdx), %xmm0
palignr $15, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
jbe LABEL(use_sse4_2_exit)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add $16, %rdx
jmp LABEL(loop_ashr_15_use_sse4_2)
@@ -1434,22 +1801,28 @@ LABEL(nibble_ashr_15_use_sse4_2):
movdqa -16(%rdi, %rdx), %xmm0
psrldq $15, %xmm0
pcmpistri $0x3a,%xmm0, %xmm0
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
cmp %r11, %rcx
jae LABEL(nibble_ashr_use_sse4_2_exit)
-#endif
+# endif
cmp $0, %ecx
ja LABEL(loop_ashr_15_use_sse4_2)
LABEL(nibble_ashr_use_sse4_2_exit):
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+# else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+# endif
.p2align 4
LABEL(use_sse4_2_exit):
jnc LABEL(strcmp_exitz_sse4_2)
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub %rcx, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
add %rcx, %rdx
lea -16(%rdi, %r9), %rdi
movzbl (%rdi, %rdx), %eax
@@ -1458,6 +1831,12 @@ LABEL(use_sse4_2_exit):
jz LABEL(use_sse4_2_ret_sse4_2)
xchg %eax, %edx
LABEL(use_sse4_2_ret_sse4_2):
+# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
+ leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rcx
+ movl (%rcx,%rdx,4), %edx
+ movl (%rcx,%rax,4), %eax
+# endif
+
sub %edx, %eax
ret
@@ -1473,13 +1852,19 @@ LABEL(ret_sse4_2):
LABEL(less16bytes_sse4_2):
bsf %rdx, %rdx /* find and store bit index in %rdx */
-#ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub %rdx, %r11
jbe LABEL(strcmp_exitz_sse4_2)
-#endif
+# endif
movzbl (%rsi, %rdx), %ecx
movzbl (%rdi, %rdx), %eax
+# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
+ leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx
+ movl (%rdx,%rcx,4), %ecx
+ movl (%rdx,%rax,4), %eax
+# endif
+
sub %ecx, %eax
ret
@@ -1488,15 +1873,27 @@ LABEL(strcmp_exitz_sse4_2):
ret
.p2align 4
+ // XXX Same as code above
LABEL(Byte0_sse4_2):
movzx (%rsi), %ecx
movzx (%rdi), %eax
+# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
+ leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx
+ movl (%rdx,%rcx,4), %ecx
+ movl (%rdx,%rax,4), %eax
+# endif
+
sub %ecx, %eax
ret
cfi_endproc
.size STRCMP_SSE42, .-STRCMP_SSE42
+# undef UCLOW_reg
+# undef UCHIGH_reg
+# undef LCQWORD_reg
+# undef TOLOWER
+
/* Put all SSE 4.2 functions together. */
.section .rodata.sse4.2,"a",@progbits
.p2align 3
@@ -1528,6 +1925,27 @@ LABEL(unaligned_table_sse4_2):
# undef END
# define END(name) \
cfi_endproc; .size STRCMP_SSE2, .-STRCMP_SSE2
+
+# ifdef USE_AS_STRCASECMP_L
+# define ENTRY2(name) \
+ .type __strcasecmp_sse2, @function; \
+ .align 16; \
+ __strcasecmp_sse2: cfi_startproc; \
+ CALL_MCOUNT
+# define END2(name) \
+ cfi_endproc; .size __strcasecmp_sse2, .-__strcasecmp_sse2
+# endif
+
+# ifdef USE_AS_STRNCASECMP_L
+# define ENTRY2(name) \
+ .type __strncasecmp_sse2, @function; \
+ .align 16; \
+ __strncasecmp_sse2: cfi_startproc; \
+ CALL_MCOUNT
+# define END2(name) \
+ cfi_endproc; .size __strncasecmp_sse2, .-__strncasecmp_sse2
+# endif
+
# undef libc_hidden_builtin_def
/* It doesn't make sense to send libc-internal strcmp calls through a PLT.
The speedup we get from using SSE4.2 instruction is likely eaten away
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strncase_l-ssse3.S
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strncase_l-ssse3.S
@@ -0,0 +1,6 @@
+#define USE_SSSE3 1
+#define USE_AS_STRNCASECMP_L
+#define NO_NOLOCALE_ALIAS
+#define STRCMP __strncasecmp_l_ssse3
+#define __strncasecmp __strncasecmp_ssse3
+#include "../strcmp.S"
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strncase_l.S
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strncase_l.S
@@ -0,0 +1,6 @@
+#define STRCMP __strncasecmp_l
+#define USE_AS_STRNCASECMP_L
+#include "strcmp.S"
+
+weak_alias (__strncasecmp_l, strncasecmp_l)
+libc_hidden_def (strncasecmp_l)
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strstr.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/x86_64/multiarch/strstr.c
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/multiarch/strstr.c
@@ -67,10 +67,10 @@
case ECX CFlag ZFlag SFlag
3 X 1 0 0/1
- 4a 0 1 0 0
- 4b 0 1 0 1
- 4c 0 < X 1 0 0/1
- 5 16 0 1 0
+ 4a 0 1 0 0
+ 4b 0 1 0 1
+ 4c 0 < X 1 0 0/1
+ 5 16 0 1 0
3. An initial ordered-comparison fragment match, we fix up to do
subsequent string comparison
@@ -147,8 +147,7 @@ __m128i_shift_right (__m128i value, int
If EOS occurs within less than 16B before 4KB boundary, we don't
cross to next page. */
-static __m128i
-__attribute__ ((section (".text.sse4.2")))
+static inline __m128i
__m128i_strloadu (const unsigned char * p)
{
int offset = ((size_t) p & (16 - 1));
@@ -164,59 +163,36 @@ __m128i_strloadu (const unsigned char *
return _mm_loadu_si128 ((__m128i *) p);
}
-#ifdef USE_AS_STRCASESTR
+#if defined USE_AS_STRCASESTR && !defined STRCASESTR_NONASCII
/* Similar to __m128i_strloadu. Convert to lower case for POSIX/C
locale. */
-
-static __m128i
-__attribute__ ((section (".text.sse4.2")))
-__m128i_strloadu_tolower_posix (const unsigned char * p)
+static inline __m128i
+__m128i_strloadu_tolower (const unsigned char *p, __m128i rangeuc,
+ __m128i u2ldelta)
{
__m128i frag = __m128i_strloadu (p);
- /* Convert frag to lower case for POSIX/C locale. */
- __m128i rangeuc = _mm_set_epi64x (0x0, 0x5a41);
- __m128i u2ldelta = _mm_set1_epi64x (0xe0e0e0e0e0e0e0e0);
- __m128i mask1 = _mm_cmpistrm (rangeuc, frag, 0x44);
- __m128i mask2 = _mm_blendv_epi8 (u2ldelta, frag, mask1);
- mask2 = _mm_sub_epi8 (mask2, u2ldelta);
- return _mm_blendv_epi8 (frag, mask2, mask1);
+#define UCLOW 0x4040404040404040ULL
+#define UCHIGH 0x5b5b5b5b5b5b5b5bULL
+#define LCQWORD 0x2020202020202020ULL
+ /* Compare if 'Z' > bytes. Inverted way to get a mask for byte <= 'Z'. */
+ __m128i r2 = _mm_cmpgt_epi8 (_mm_set1_epi64x (UCHIGH), frag);
+ /* Compare if bytes are > 'A' - 1. */
+ __m128i r1 = _mm_cmpgt_epi8 (frag, _mm_set1_epi64x (UCLOW));
+ /* Mask byte == ff if byte(r2) <= 'Z' and byte(r1) > 'A' - 1. */
+ __m128i mask = _mm_and_si128 (r2, r1);
+ /* Apply lowercase bit 6 mask for above mask bytes == ff. */
+ return _mm_or_si128 (frag, _mm_and_si128 (mask, _mm_set1_epi64x (LCQWORD)));
}
-/* Similar to __m128i_strloadu. Convert to lower case for none-POSIX/C
- locale. */
-
-static __m128i
-__attribute__ ((section (".text.sse4.2")))
-__m128i_strloadu_tolower (const unsigned char * p)
-{
- union
- {
- char b[16];
- __m128i x;
- } u;
-
- for (int i = 0; i < 16; i++)
- if (p[i] == 0)
- {
- u.b[i] = 0;
- break;
- }
- else
- u.b[i] = tolower (p[i]);
-
- return u.x;
-}
#endif
/* Calculate Knuth-Morris-Pratt string searching algorithm (or KMP
algorithm) overlap for a fully populated 16B vector.
Input parameter: 1st 16Byte loaded from the reference string of a
strstr function.
- We don't use KMP algorithm if reference string is less than 16B.
- */
-
+ We don't use KMP algorithm if reference string is less than 16B. */
static int
__inline__ __attribute__ ((__always_inline__,))
KMP16Bovrlap (__m128i s2)
@@ -236,7 +212,7 @@ KMP16Bovrlap (__m128i s2)
return 1;
else if (!k1)
{
- /* There are al least two ditinct char in s2. If byte 0 and 1 are
+ /* There are al least two distinct chars in s2. If byte 0 and 1 are
idential and the distinct value lies farther down, we can deduce
the next byte offset to restart full compare is least no earlier
than byte 3. */
@@ -256,23 +232,30 @@ STRSTR_SSE42 (const unsigned char *s1, c
#define p1 s1
const unsigned char *p2 = s2;
- if (p2[0] == '\0')
+#ifndef STRCASESTR_NONASCII
+ if (__builtin_expect (p2[0] == '\0', 0))
return (char *) p1;
- if (p1[0] == '\0')
+ if (__builtin_expect (p1[0] == '\0', 0))
return NULL;
/* Check if p1 length is 1 byte long. */
- if (p1[1] == '\0')
+ if (__builtin_expect (p1[1] == '\0', 0))
return p2[1] == '\0' && CMPBYTE (p1[0], p2[0]) ? (char *) p1 : NULL;
+#endif
#ifdef USE_AS_STRCASESTR
- __m128i (*strloadu) (const unsigned char *);
-
- if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_NONASCII_CASE) == 0)
- strloadu = __m128i_strloadu_tolower_posix;
- else
- strloadu = __m128i_strloadu_tolower;
+# ifndef STRCASESTR_NONASCII
+ if (__builtin_expect (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_NONASCII_CASE)
+ != 0, 0))
+ return __strcasestr_sse42_nonascii (s1, s2);
+
+ const __m128i rangeuc = _mm_set_epi64x (0x0, 0x5a41);
+ const __m128i u2ldelta = _mm_set1_epi64x (0xe0e0e0e0e0e0e0e0);
+# define strloadu(p) __m128i_strloadu_tolower (p, rangeuc, u2ldelta)
+# else
+# define strloadu __m128i_strloadu_tolower
+# endif
#else
# define strloadu __m128i_strloadu
#endif
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strcasecmp.S
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strcasecmp.S
@@ -0,0 +1 @@
+/* In strcasecmp_l.S. */
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strcasecmp_l-nonascii.c
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strcasecmp_l-nonascii.c
@@ -0,0 +1,8 @@
+#include <string.h>
+
+extern int __strcasecmp_l_nonascii (__const char *__s1, __const char *__s2,
+ __locale_t __loc);
+
+#define __strcasecmp_l __strcasecmp_l_nonascii
+#define USE_IN_EXTENDED_LOCALE_MODEL 1
+#include <string/strcasecmp.c>
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strcasecmp_l.S
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strcasecmp_l.S
@@ -0,0 +1,6 @@
+#define STRCMP __strcasecmp_l
+#define USE_AS_STRCASECMP_L
+#include "strcmp.S"
+
+weak_alias (__strcasecmp_l, strcasecmp_l)
+libc_hidden_def (strcasecmp_l)
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strcmp.S
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/x86_64/strcmp.S
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strcmp.S
@@ -51,6 +51,31 @@
je LABEL(strcmp_exitz); \
mov %r9, %r11
+#elif defined USE_AS_STRCASECMP_L
+# include "locale-defines.h"
+
+/* No support for strcasecmp outside libc so far since it is not needed. */
+# ifdef NOT_IN_lib
+# error "strcasecmp_l not implemented so far"
+# endif
+
+# define UPDATE_STRNCMP_COUNTER
+#elif defined USE_AS_STRNCASECMP_L
+# include "locale-defines.h"
+
+/* No support for strncasecmp outside libc so far since it is not needed. */
+# ifdef NOT_IN_lib
+# error "strncasecmp_l not implemented so far"
+# endif
+
+# define UPDATE_STRNCMP_COUNTER \
+ /* calculate left number to compare */ \
+ lea -16(%rcx, %r11), %r9; \
+ cmp %r9, %r11; \
+ jb LABEL(strcmp_exitz); \
+ test %r9, %r9; \
+ je LABEL(strcmp_exitz); \
+ mov %r9, %r11
#else
# define UPDATE_STRNCMP_COUNTER
# ifndef STRCMP
@@ -64,6 +89,46 @@
.section .text.ssse3,"ax",@progbits
#endif
+#ifdef USE_AS_STRCASECMP_L
+# ifndef ENTRY2
+# define ENTRY2(name) ENTRY (name)
+# define END2(name) END (name)
+# endif
+
+ENTRY2 (__strcasecmp)
+ movq __libc_tsd_LOCALE@gottpoff(%rip),%rax
+ movq %fs:(%rax),%rdx
+
+ // XXX 5 byte should be before the function
+ /* 5-byte NOP. */
+ .byte 0x0f,0x1f,0x44,0x00,0x00
+END2 (__strcasecmp)
+# ifndef NO_NOLOCALE_ALIAS
+weak_alias (__strcasecmp, strcasecmp)
+libc_hidden_def (__strcasecmp)
+# endif
+ /* FALLTHROUGH to strcasecmp_l. */
+#elif defined USE_AS_STRNCASECMP_L
+# ifndef ENTRY2
+# define ENTRY2(name) ENTRY (name)
+# define END2(name) END (name)
+# endif
+
+ENTRY2 (__strncasecmp)
+ movq __libc_tsd_LOCALE@gottpoff(%rip),%rax
+ movq %fs:(%rax),%rcx
+
+ // XXX 5 byte should be before the function
+ /* 5-byte NOP. */
+ .byte 0x0f,0x1f,0x44,0x00,0x00
+END2 (__strncasecmp)
+# ifndef NO_NOLOCALE_ALIAS
+weak_alias (__strncasecmp, strncasecmp)
+libc_hidden_def (__strncasecmp)
+# endif
+ /* FALLTHROUGH to strncasecmp_l. */
+#endif
+
ENTRY (BP_SYM (STRCMP))
#ifdef NOT_IN_libc
/* Simple version since we can't use SSE registers in ld.so. */
@@ -84,10 +149,32 @@ L(neq): movl $1, %eax
ret
END (BP_SYM (STRCMP))
#else /* NOT_IN_libc */
+# ifdef USE_AS_STRCASECMP_L
+ /* We have to fall back on the C implementation for locales
+ with encodings not matching ASCII for single bytes. */
+# if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
+ movq LOCALE_T___LOCALES+LC_CTYPE*8(%rdx), %rax
+# else
+ movq (%rdx), %rax
+# endif
+ testl $0, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%rax)
+ jne __strcasecmp_l_nonascii
+# elif defined USE_AS_STRNCASECMP_L
+ /* We have to fall back on the C implementation for locales
+ with encodings not matching ASCII for single bytes. */
+# if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
+ movq LOCALE_T___LOCALES+LC_CTYPE*8(%rcx), %rax
+# else
+ movq (%rcx), %rax
+# endif
+ testl $0, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%rax)
+ jne __strncasecmp_l_nonascii
+# endif
+
/*
* This implementation uses SSE to compare up to 16 bytes at a time.
*/
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
test %rdx, %rdx
je LABEL(strcmp_exitz)
cmp $1, %rdx
@@ -99,6 +186,26 @@ END (BP_SYM (STRCMP))
/* Use 64bit AND here to avoid long NOP padding. */
and $0x3f, %rcx /* rsi alignment in cache line */
and $0x3f, %rax /* rdi alignment in cache line */
+# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
+ .section .rodata.cst16,"aM",@progbits,16
+ .align 16
+.Lbelowupper:
+ .quad 0x4040404040404040
+ .quad 0x4040404040404040
+.Ltopupper:
+ .quad 0x5b5b5b5b5b5b5b5b
+ .quad 0x5b5b5b5b5b5b5b5b
+.Ltouppermask:
+ .quad 0x2020202020202020
+ .quad 0x2020202020202020
+ .previous
+ movdqa .Lbelowupper(%rip), %xmm5
+# define UCLOW_reg %xmm5
+ movdqa .Ltopupper(%rip), %xmm6
+# define UCHIGH_reg %xmm6
+ movdqa .Ltouppermask(%rip), %xmm7
+# define LCQWORD_reg %xmm7
+# endif
cmp $0x30, %ecx
ja LABEL(crosscache) /* rsi: 16-byte load will cross cache line */
cmp $0x30, %eax
@@ -107,6 +214,26 @@ END (BP_SYM (STRCMP))
movlpd (%rsi), %xmm2
movhpd 8(%rdi), %xmm1
movhpd 8(%rsi), %xmm2
+# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
+# define TOLOWER(reg1, reg2) \
+ movdqa reg1, %xmm8; \
+ movdqa UCHIGH_reg, %xmm9; \
+ movdqa reg2, %xmm10; \
+ movdqa UCHIGH_reg, %xmm11; \
+ pcmpgtb UCLOW_reg, %xmm8; \
+ pcmpgtb reg1, %xmm9; \
+ pcmpgtb UCLOW_reg, %xmm10; \
+ pcmpgtb reg2, %xmm11; \
+ pand %xmm9, %xmm8; \
+ pand %xmm11, %xmm10; \
+ pand LCQWORD_reg, %xmm8; \
+ pand LCQWORD_reg, %xmm10; \
+ por %xmm8, reg1; \
+ por %xmm10, reg2
+ TOLOWER (%xmm1, %xmm2)
+# else
+# define TOLOWER(reg1, reg2)
+# endif
pxor %xmm0, %xmm0 /* clear %xmm0 for null char checks */
pcmpeqb %xmm1, %xmm0 /* Any null chars? */
pcmpeqb %xmm2, %xmm1 /* compare first 16 bytes for equality */
@@ -114,7 +241,7 @@ END (BP_SYM (STRCMP))
pmovmskb %xmm1, %edx
sub $0xffff, %edx /* if first 16 bytes are same, edx == 0xffff */
jnz LABEL(less16bytes) /* If not, find different value or null char */
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz) /* finish comparision */
# endif
@@ -159,7 +286,13 @@ LABEL(ashr_0):
movdqa (%rsi), %xmm1
pxor %xmm0, %xmm0 /* clear %xmm0 for null char check */
pcmpeqb %xmm1, %xmm0 /* Any null chars? */
+# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
pcmpeqb (%rdi), %xmm1 /* compare 16 bytes for equality */
+# else
+ movdqa (%rdi), %xmm2
+ TOLOWER (%xmm1, %xmm2)
+ pcmpeqb %xmm2, %xmm1 /* compare 16 bytes for equality */
+# endif
psubb %xmm0, %xmm1 /* packed sub of comparison results*/
pmovmskb %xmm1, %r9d
shr %cl, %edx /* adjust 0xffff for offset */
@@ -183,6 +316,7 @@ LABEL(ashr_0):
LABEL(loop_ashr_0):
movdqa (%rsi, %rcx), %xmm1
movdqa (%rdi, %rcx), %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -191,13 +325,14 @@ LABEL(loop_ashr_0):
sub $0xffff, %edx
jnz LABEL(exit) /* mismatch or null char seen */
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
add $16, %rcx
movdqa (%rsi, %rcx), %xmm1
movdqa (%rdi, %rcx), %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -205,7 +340,7 @@ LABEL(loop_ashr_0):
pmovmskb %xmm1, %edx
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -214,7 +349,7 @@ LABEL(loop_ashr_0):
/*
* The following cases will be handled by ashr_1
- * rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
+ * rcx(offset of rsi) rax(offset of rdi) relative offset corresponding case
* n(15) n -15 0(15 +(n-15) - n) ashr_1
*/
.p2align 4
@@ -224,6 +359,7 @@ LABEL(ashr_1):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0 /* Any null chars? */
pslldq $15, %xmm2 /* shift first string to align with second */
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2 /* compare 16 bytes for equality */
psubb %xmm0, %xmm2 /* packed sub of comparison results*/
pmovmskb %xmm2, %r9d
@@ -263,6 +399,7 @@ LABEL(gobble_ashr_1):
# else
palignr $1, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -271,7 +408,7 @@ LABEL(gobble_ashr_1):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -292,6 +429,7 @@ LABEL(gobble_ashr_1):
# else
palignr $1, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -300,7 +438,7 @@ LABEL(gobble_ashr_1):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -319,8 +457,8 @@ LABEL(nibble_ashr_1):
test $0xfffe, %edx
jnz LABEL(ashr_1_exittail) /* find null char*/
-# ifdef USE_AS_STRNCMP
- cmp $14, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $15, %r11
jbe LABEL(ashr_1_exittail)
# endif
@@ -351,6 +489,7 @@ LABEL(ashr_2):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $14, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -390,6 +529,7 @@ LABEL(gobble_ashr_2):
# else
palignr $2, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -398,7 +538,7 @@ LABEL(gobble_ashr_2):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -420,6 +560,7 @@ LABEL(gobble_ashr_2):
# else
palignr $2, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -428,7 +569,7 @@ LABEL(gobble_ashr_2):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -444,8 +585,8 @@ LABEL(nibble_ashr_2):
test $0xfffc, %edx
jnz LABEL(ashr_2_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $13, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $14, %r11
jbe LABEL(ashr_2_exittail)
# endif
@@ -472,6 +613,7 @@ LABEL(ashr_3):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $13, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -512,6 +654,7 @@ LABEL(gobble_ashr_3):
# else
palignr $3, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -520,7 +663,7 @@ LABEL(gobble_ashr_3):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -542,6 +685,7 @@ LABEL(gobble_ashr_3):
# else
palignr $3, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -550,7 +694,7 @@ LABEL(gobble_ashr_3):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -566,8 +710,8 @@ LABEL(nibble_ashr_3):
test $0xfff8, %edx
jnz LABEL(ashr_3_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $12, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $13, %r11
jbe LABEL(ashr_3_exittail)
# endif
@@ -594,6 +738,7 @@ LABEL(ashr_4):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $12, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -634,6 +779,7 @@ LABEL(gobble_ashr_4):
# else
palignr $4, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -642,7 +788,7 @@ LABEL(gobble_ashr_4):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -664,6 +810,7 @@ LABEL(gobble_ashr_4):
# else
palignr $4, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -672,7 +819,7 @@ LABEL(gobble_ashr_4):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -688,8 +835,8 @@ LABEL(nibble_ashr_4):
test $0xfff0, %edx
jnz LABEL(ashr_4_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $11, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $12, %r11
jbe LABEL(ashr_4_exittail)
# endif
@@ -716,6 +863,7 @@ LABEL(ashr_5):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $11, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -756,6 +904,7 @@ LABEL(gobble_ashr_5):
# else
palignr $5, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -764,7 +913,7 @@ LABEL(gobble_ashr_5):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -786,6 +935,7 @@ LABEL(gobble_ashr_5):
# else
palignr $5, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -794,7 +944,7 @@ LABEL(gobble_ashr_5):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -810,8 +960,8 @@ LABEL(nibble_ashr_5):
test $0xffe0, %edx
jnz LABEL(ashr_5_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $10, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $11, %r11
jbe LABEL(ashr_5_exittail)
# endif
@@ -838,6 +988,7 @@ LABEL(ashr_6):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $10, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -878,6 +1029,7 @@ LABEL(gobble_ashr_6):
# else
palignr $6, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -886,7 +1038,7 @@ LABEL(gobble_ashr_6):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -908,6 +1060,7 @@ LABEL(gobble_ashr_6):
# else
palignr $6, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -916,7 +1069,7 @@ LABEL(gobble_ashr_6):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -932,8 +1085,8 @@ LABEL(nibble_ashr_6):
test $0xffc0, %edx
jnz LABEL(ashr_6_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $9, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $10, %r11
jbe LABEL(ashr_6_exittail)
# endif
@@ -960,6 +1113,7 @@ LABEL(ashr_7):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $9, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1000,6 +1154,7 @@ LABEL(gobble_ashr_7):
# else
palignr $7, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1008,7 +1163,7 @@ LABEL(gobble_ashr_7):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1030,6 +1185,7 @@ LABEL(gobble_ashr_7):
# else
palignr $7, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1038,7 +1194,7 @@ LABEL(gobble_ashr_7):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1054,8 +1210,8 @@ LABEL(nibble_ashr_7):
test $0xff80, %edx
jnz LABEL(ashr_7_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $8, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $9, %r11
jbe LABEL(ashr_7_exittail)
# endif
@@ -1082,6 +1238,7 @@ LABEL(ashr_8):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $8, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1122,6 +1279,7 @@ LABEL(gobble_ashr_8):
# else
palignr $8, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1130,7 +1288,7 @@ LABEL(gobble_ashr_8):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1152,6 +1310,7 @@ LABEL(gobble_ashr_8):
# else
palignr $8, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1160,7 +1319,7 @@ LABEL(gobble_ashr_8):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1176,8 +1335,8 @@ LABEL(nibble_ashr_8):
test $0xff00, %edx
jnz LABEL(ashr_8_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $7, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $8, %r11
jbe LABEL(ashr_8_exittail)
# endif
@@ -1204,6 +1363,7 @@ LABEL(ashr_9):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $7, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1244,6 +1404,7 @@ LABEL(gobble_ashr_9):
# else
palignr $9, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1252,7 +1413,7 @@ LABEL(gobble_ashr_9):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1274,6 +1435,7 @@ LABEL(gobble_ashr_9):
# else
palignr $9, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1282,7 +1444,7 @@ LABEL(gobble_ashr_9):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1298,8 +1460,8 @@ LABEL(nibble_ashr_9):
test $0xfe00, %edx
jnz LABEL(ashr_9_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $6, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $7, %r11
jbe LABEL(ashr_9_exittail)
# endif
@@ -1326,6 +1488,7 @@ LABEL(ashr_10):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $6, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1366,6 +1529,7 @@ LABEL(gobble_ashr_10):
# else
palignr $10, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1374,7 +1538,7 @@ LABEL(gobble_ashr_10):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1396,6 +1560,7 @@ LABEL(gobble_ashr_10):
# else
palignr $10, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1404,7 +1569,7 @@ LABEL(gobble_ashr_10):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1420,8 +1585,8 @@ LABEL(nibble_ashr_10):
test $0xfc00, %edx
jnz LABEL(ashr_10_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $5, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $6, %r11
jbe LABEL(ashr_10_exittail)
# endif
@@ -1448,6 +1613,7 @@ LABEL(ashr_11):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $5, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1488,6 +1654,7 @@ LABEL(gobble_ashr_11):
# else
palignr $11, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1496,7 +1663,7 @@ LABEL(gobble_ashr_11):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1518,6 +1685,7 @@ LABEL(gobble_ashr_11):
# else
palignr $11, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1526,7 +1694,7 @@ LABEL(gobble_ashr_11):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1542,8 +1710,8 @@ LABEL(nibble_ashr_11):
test $0xf800, %edx
jnz LABEL(ashr_11_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $4, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $5, %r11
jbe LABEL(ashr_11_exittail)
# endif
@@ -1570,6 +1738,7 @@ LABEL(ashr_12):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $4, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1610,6 +1779,7 @@ LABEL(gobble_ashr_12):
# else
palignr $12, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1618,7 +1788,7 @@ LABEL(gobble_ashr_12):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1640,6 +1810,7 @@ LABEL(gobble_ashr_12):
# else
palignr $12, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1648,7 +1819,7 @@ LABEL(gobble_ashr_12):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1664,8 +1835,8 @@ LABEL(nibble_ashr_12):
test $0xf000, %edx
jnz LABEL(ashr_12_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $3, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $4, %r11
jbe LABEL(ashr_12_exittail)
# endif
@@ -1692,6 +1863,7 @@ LABEL(ashr_13):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $3, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1732,6 +1904,7 @@ LABEL(gobble_ashr_13):
# else
palignr $13, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1740,7 +1913,7 @@ LABEL(gobble_ashr_13):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1762,6 +1935,7 @@ LABEL(gobble_ashr_13):
# else
palignr $13, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1770,7 +1944,7 @@ LABEL(gobble_ashr_13):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1786,8 +1960,8 @@ LABEL(nibble_ashr_13):
test $0xe000, %edx
jnz LABEL(ashr_13_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $2, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $3, %r11
jbe LABEL(ashr_13_exittail)
# endif
@@ -1814,6 +1988,7 @@ LABEL(ashr_14):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $2, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1854,6 +2029,7 @@ LABEL(gobble_ashr_14):
# else
palignr $14, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1862,7 +2038,7 @@ LABEL(gobble_ashr_14):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1884,6 +2060,7 @@ LABEL(gobble_ashr_14):
# else
palignr $14, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1892,7 +2069,7 @@ LABEL(gobble_ashr_14):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP | defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -1908,8 +2085,8 @@ LABEL(nibble_ashr_14):
test $0xc000, %edx
jnz LABEL(ashr_14_exittail)
-# ifdef USE_AS_STRNCMP
- cmp $1, %r11
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmp $2, %r11
jbe LABEL(ashr_14_exittail)
# endif
@@ -1936,6 +2113,7 @@ LABEL(ashr_15):
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $1, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
@@ -1978,6 +2156,7 @@ LABEL(gobble_ashr_15):
# else
palignr $15, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -1986,7 +2165,7 @@ LABEL(gobble_ashr_15):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -2008,6 +2187,7 @@ LABEL(gobble_ashr_15):
# else
palignr $15, %xmm3, %xmm2 /* merge into one 16byte value */
# endif
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm2, %xmm1
@@ -2016,7 +2196,7 @@ LABEL(gobble_ashr_15):
sub $0xffff, %edx
jnz LABEL(exit)
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub $16, %r11
jbe LABEL(strcmp_exitz)
# endif
@@ -2032,9 +2212,9 @@ LABEL(nibble_ashr_15):
test $0x8000, %edx
jnz LABEL(ashr_15_exittail)
-# ifdef USE_AS_STRNCMP
- test %r11, %r11
- je LABEL(ashr_15_exittail)
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
+ cmpq $1, %r11
+ jbe LABEL(ashr_15_exittail)
# endif
pxor %xmm0, %xmm0
@@ -2049,6 +2229,7 @@ LABEL(ashr_15_exittail):
.p2align 4
LABEL(aftertail):
+ TOLOWER (%xmm1, %xmm3)
pcmpeqb %xmm3, %xmm1
psubb %xmm0, %xmm1
pmovmskb %xmm1, %edx
@@ -2069,13 +2250,19 @@ LABEL(ret):
LABEL(less16bytes):
bsf %rdx, %rdx /* find and store bit index in %rdx */
-# ifdef USE_AS_STRNCMP
+# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
sub %rdx, %r11
jbe LABEL(strcmp_exitz)
# endif
movzbl (%rsi, %rdx), %ecx
movzbl (%rdi, %rdx), %eax
+# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
+ leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx
+ movl (%rdx,%rcx,4), %ecx
+ movl (%rdx,%rax,4), %eax
+# endif
+
sub %ecx, %eax
ret
@@ -2088,6 +2275,12 @@ LABEL(Byte0):
movzx (%rsi), %ecx
movzx (%rdi), %eax
+# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
+ leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx
+ movl (%rdx,%rcx,4), %ecx
+ movl (%rdx,%rax,4), %eax
+# endif
+
sub %ecx, %eax
ret
END (BP_SYM (STRCMP))
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strncase.S
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strncase.S
@@ -0,0 +1 @@
+/* In strncase_l.S. */
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strncase_l-nonascii.c
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strncase_l-nonascii.c
@@ -0,0 +1,8 @@
+#include <string.h>
+
+extern int __strncasecmp_l_nonascii (__const char *__s1, __const char *__s2,
+ size_t __n, __locale_t __loc);
+
+#define __strncasecmp_l __strncasecmp_l_nonascii
+#define USE_IN_EXTENDED_LOCALE_MODEL 1
+#include <string/strncase.c>
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strncase_l.S
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strncase_l.S
@@ -0,0 +1,6 @@
+#define STRCMP __strncasecmp_l
+#define USE_AS_STRNCASECMP_L
+#include "strcmp.S"
+
+weak_alias (__strncasecmp_l, strncasecmp_l)
+libc_hidden_def (strncasecmp_l)
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strnlen.S
===================================================================
--- /dev/null
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/strnlen.S
@@ -0,0 +1,64 @@
+/* strnlen(str,maxlen) -- determine the length of the string STR up to MAXLEN.
+ Copyright (C) 2010 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@redhat.com>.
+ This file is part of the GNU C Library.
+
+ 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 <sysdep.h>
+
+
+ .text
+ENTRY(__strnlen)
+ movq %rsi, %rax
+ testq %rsi, %rsi
+ jz 3f
+ pxor %xmm2, %xmm2
+ movq %rdi, %rcx
+ movq %rdi, %r8
+ movq $16, %r9
+ andq $~15, %rdi
+ movdqa %xmm2, %xmm1
+ pcmpeqb (%rdi), %xmm2
+ orl $0xffffffff, %r10d
+ subq %rdi, %rcx
+ shll %cl, %r10d
+ subq %rcx, %r9
+ pmovmskb %xmm2, %edx
+ andl %r10d, %edx
+ jnz 1f
+ subq %r9, %rsi
+ jbe 3f
+
+2: movdqa 16(%rdi), %xmm0
+ leaq 16(%rdi), %rdi
+ pcmpeqb %xmm1, %xmm0
+ pmovmskb %xmm0, %edx
+ testl %edx, %edx
+ jnz 1f
+ subq $16, %rsi
+ jnbe 2b
+3: ret
+
+1: subq %r8, %rdi
+ bsfl %edx, %edx
+ addq %rdi, %rdx
+ cmpq %rdx, %rax
+ cmovnbq %rdx, %rax
+ ret
+END(__strnlen)
+weak_alias (__strnlen, strnlen)
+libc_hidden_def (strnlen)
Index: glibc-2.12-2-gc4ccff1/wcsmbs/wcsatcliff.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/wcsmbs/wcsatcliff.c
+++ glibc-2.12-2-gc4ccff1/wcsmbs/wcsatcliff.c
@@ -16,6 +16,8 @@
#define MEMCPY wmemcpy
#define MEMPCPY wmempcpy
#define MEMCHR wmemchr
+#define STRCMP wcscmp
+#define STRNCMP wcsncmp
#include "../string/stratcliff.c"