From c8d94176d320d267f11d6011f7b2dcf9679425cc Mon Sep 17 00:00:00 2001 From: H.J. Lu Date: Thu, 15 Apr 2010 07:49:30 -0700 Subject: [PATCH] Fix bugs in x86-32 strcmp-sse4.S and strcmp-ssse3.S --- string/test-strncmp.c | 39 +++++++++++++++++++++++++--- sysdeps/i386/i686/multiarch/strcmp-sse4.S | 4 +- sysdeps/i386/i686/multiarch/strcmp-ssse3.S | 11 ++++--- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/string/test-strncmp.c b/string/test-strncmp.c index 5adf0eb..3687879 100644 --- a/string/test-strncmp.c +++ b/string/test-strncmp.c @@ -1,5 +1,5 @@ /* Test and measure strncmp functions. - Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2002, 2003, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Jakub Jelinek , 1999. @@ -51,8 +51,8 @@ stupid_strncmp (const char *s1, const char *s2, size_t n) return ret; } -static void -do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n, +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); @@ -63,9 +63,19 @@ do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n, error (0, 0, "Wrong result in function %s %d %d", impl->name, result, exp_result); ret = 1; - return; + return -1; } + return 0; +} + +static void +do_one_test (impl_t *impl, const 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)); @@ -283,6 +293,25 @@ do_random_tests (void) } } +static void +check1 (void) +{ + char *s1 = (char *)(buf1 + 0xb2c); + char *s2 = (char *)(buf1 + 0xfd8); + size_t i; + int exp_result; + + strcpy(s1, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs"); + strcpy(s2, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkLMNOPQRSTUV"); + + for (i = 0; i < 80; i++) + { + exp_result = simple_strncmp (s1, s2, i); + FOR_EACH_IMPL (impl, 0) + check_result (impl, s1, s2, i, exp_result); + } +} + int test_main (void) { @@ -290,6 +319,8 @@ test_main (void) test_init (); + check1 (); + printf ("%23s", ""); FOR_EACH_IMPL (impl, 0) printf ("\t%s", impl->name); diff --git a/sysdeps/i386/i686/multiarch/strcmp-sse4.S b/sysdeps/i386/i686/multiarch/strcmp-sse4.S index 81d6ec6..0de0a11 100644 --- a/sysdeps/i386/i686/multiarch/strcmp-sse4.S +++ b/sysdeps/i386/i686/multiarch/strcmp-sse4.S @@ -223,8 +223,8 @@ L(crosspage): inc %edx cmp $15, %edx jle L(crosspage) - add $16, %edi - add $16, %esi + add %edx, %edi + add %edx, %esi jmp L(check_offset) .p2align 4 diff --git a/sysdeps/i386/i686/multiarch/strcmp-ssse3.S b/sysdeps/i386/i686/multiarch/strcmp-ssse3.S index 40994c0..a4de225 100644 --- a/sysdeps/i386/i686/multiarch/strcmp-ssse3.S +++ b/sysdeps/i386/i686/multiarch/strcmp-ssse3.S @@ -1484,17 +1484,18 @@ L(gobble_ashr_12): sub $0xffff, %esi jnz L(exit) +#ifdef USE_AS_STRNCMP + cmp $16, %ebp + lea -16(%ebp), %ebp + jbe L(more8byteseq) +#endif + add $16, %ecx movdqa %xmm4, %xmm3 add $16, %edi jg L(nibble_ashr_12) -#ifdef USE_AS_STRNCMP - cmp $16, %ebp - lea -16(%ebp), %ebp - jbe L(more8byteseq) -#endif movdqa (%eax, %ecx), %xmm1 movdqa (%edx, %ecx), %xmm2 movdqa %xmm2, %xmm4 -- 1.7.0.5