diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | string/test-strncmp.c | 60 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/strncmp.S | 17 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/strncmp.S | 17 |
4 files changed, 89 insertions, 16 deletions
@@ -1,3 +1,14 @@ +2005-11-17 Steven Munroe <sjmunroe@us.ibm.com> + + [BZ #1877] + * string/test-strncmp.c (do_test_limit): New function. + (do_test) Add cast to eliminate compiler warnings. + (do_random_tests) Add cast to eliminate compiler warnings. + (test_main) Add do_test_limit tests. + * sysdeps/powerpc/powerpc32/strncmp.S: Test length before unaligned + load. + * sysdeps/powerpc/powerpc64/strncmp.S: Likewise. + 2005-11-17 Ulrich Drepper <drepper@redhat.com> * include/resolv.h: Include <stdbool.h>. diff --git a/string/test-strncmp.c b/string/test-strncmp.c index 431b64d..4726f87 100644 --- a/string/test-strncmp.c +++ b/string/test-strncmp.c @@ -86,6 +86,46 @@ do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n, } static void +do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char, + int exp_result) +{ + size_t i; + char *s1, *s2; + + if (n == 0) + return; + + align1 &= 7; + + align2 &= 7; + + s1 = (char*)(buf1 + page_size - n); + s2 = (char*)(buf2 + page_size - n); + + for (i = 0; i < n; i++) + s1[i] = s2[i] = 1 + 23 * i % max_char; + + if (len < n) + { + s1[len] = 0; + s2[len] = 0; + if (exp_result < 0) + s2[len] = 32; + else if (exp_result > 0) + s1[len] = 64; + } + + if (HP_TIMING_AVAIL) + printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, 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_test (size_t align1, size_t align2, size_t len, size_t n, int max_char, int exp_result) { @@ -103,8 +143,8 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char, if (align2 + n + 1 >= page_size) return; - s1 = buf1 + align1; - s2 = buf2 + align2; + s1 = (char*)(buf1 + align1); + s2 = (char*)(buf2 + align2); for (i = 0; i < n; i++) s1[i] = s2[i] = 1 + 23 * i % max_char; @@ -124,7 +164,7 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char, printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); FOR_EACH_IMPL (impl, 0) - do_one_test (impl, s1, s2, n, exp_result); + do_one_test (impl, (char*)s1, (char*)s2, n, exp_result); if (HP_TIMING_AVAIL) putchar ('\n'); @@ -208,7 +248,7 @@ do_random_tests (void) FOR_EACH_IMPL (impl, 1) { - r = CALL (impl, p1 + align1, p2 + align2, size); + r = CALL (impl, (char*)(p1 + align1), (char*)(p2 + align2), size); /* Test whether on 64-bit architectures where ABI requires callee to promote has the promotion been done. */ asm ("" : "=g" (r) : "0" (r)); @@ -272,6 +312,18 @@ test_main (void) do_test (2 * i, i, 8 << i, 16 << i, 255, 1); } + for (i = 1; i < 8; ++i) + { + do_test_limit (0, 0, 17 - i, 16 - i, 127, 0); + do_test_limit (0, 0, 17 - i, 16 - i, 255, 0); + do_test_limit (0, 0, 15 - i, 16 - i, 127, 0); + do_test_limit (0, 0, 15 - i, 16 - i, 127, 1); + do_test_limit (0, 0, 15 - i, 16 - i, 127, -1); + do_test_limit (0, 0, 15 - i, 16 - i, 255, 0); + do_test_limit (0, 0, 15 - i, 16 - i, 255, 1); + do_test_limit (0, 0, 15 - i, 16 - i, 255, -1); + } + do_random_tests (); return ret; } diff --git a/sysdeps/powerpc/powerpc32/strncmp.S b/sysdeps/powerpc/powerpc32/strncmp.S index 3b33bb9..3e0fff5 100644 --- a/sysdeps/powerpc/powerpc32/strncmp.S +++ b/sysdeps/powerpc/powerpc32/strncmp.S @@ -47,6 +47,7 @@ EALIGN (BP_SYM(strncmp), 4, 0) lis r7F7F, 0x7f7f dcbt 0,rSTR2 clrlwi. rTMP, rTMP, 30 + cmplwi cr1, rN, 0 lis rFEFE, -0x101 bne L(unaligned) /* We are word alligned so set up for two loops. first a word @@ -54,7 +55,8 @@ EALIGN (BP_SYM(strncmp), 4, 0) srwi. rTMP, rN, 2 clrlwi rN, rN, 30 addi rFEFE, rFEFE, -0x101 - addi r7F7F, r7F7F, 0x7f7f + addi r7F7F, r7F7F, 0x7f7f + cmplwi cr1, rN, 0 beq L(unaligned) mtctr rTMP /* Power4 wants mtctr 1st in dispatch group. */ @@ -122,16 +124,19 @@ L(tail): addi rSTR1, rSTR1, 4 bne- cr1, L(different) addi rSTR2, rSTR2, 4 + cmplwi cr1, rN, 0 L(unaligned): mtctr rN /* Power4 wants mtctr 1st in dispatch group */ - cmpwi rN,0 - lbz rWORD1, 0(rSTR1) - lbz rWORD2, 0(rSTR2) - bgt L(u1) + bgt cr1, L(uz) L(ux): li rRTN, 0 blr - + .align 4 +L(uz): + lbz rWORD1, 0(rSTR1) + lbz rWORD2, 0(rSTR2) + nop + b L(u1) L(u0): lbzu rWORD2, 1(rSTR2) L(u1): diff --git a/sysdeps/powerpc/powerpc64/strncmp.S b/sysdeps/powerpc/powerpc64/strncmp.S index 04bdc2f..34479e2 100644 --- a/sysdeps/powerpc/powerpc64/strncmp.S +++ b/sysdeps/powerpc/powerpc64/strncmp.S @@ -48,6 +48,7 @@ EALIGN (BP_SYM(strncmp), 4, 0) lis r7F7F, 0x7f7f dcbt 0,rSTR2 clrldi. rTMP, rTMP, 61 + cmpldi cr1, rN, 0 lis rFEFE, -0x101 bne L(unaligned) /* We are doubleword alligned so set up for two loops. first a double word @@ -55,7 +56,8 @@ EALIGN (BP_SYM(strncmp), 4, 0) srdi. rTMP, rN, 3 clrldi rN, rN, 61 addi rFEFE, rFEFE, -0x101 - addi r7F7F, r7F7F, 0x7f7f + addi r7F7F, r7F7F, 0x7f7f + cmpldi cr1, rN, 0 beq L(unaligned) mtctr rTMP /* Power4 wants mtctr 1st in dispatch group. */ @@ -126,16 +128,19 @@ L(tail): addi rSTR1, rSTR1, 8 bne- cr1, L(different) addi rSTR2, rSTR2, 8 + cmpldi cr1, rN, 0 L(unaligned): mtctr rN /* Power4 wants mtctr 1st in dispatch group */ - cmpdi rN,0 - lbz rWORD1, 0(rSTR1) - lbz rWORD2, 0(rSTR2) - bgt L(u1) + bgt cr1, L(uz) L(ux): li rRTN, 0 blr - + .align 4 +L(uz): + lbz rWORD1, 0(rSTR1) + lbz rWORD2, 0(rSTR2) + nop + b L(u1) L(u0): lbzu rWORD2, 1(rSTR2) L(u1): |