]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Optimize strcmp more and add strncmp, strcasecmp, strncasecmp implementations.
authorOndřej Bílka <neleai@seznam.cz>
Fri, 19 Jun 2015 15:36:06 +0000 (17:36 +0200)
committerOndřej Bílka <neleai@seznam.cz>
Wed, 24 Jun 2015 10:48:30 +0000 (12:48 +0200)
13 files changed:
sysdeps/x86_64/locale-defines.sym
sysdeps/x86_64/multiarch/Makefile
sysdeps/x86_64/multiarch/ifunc-impl-list.c
sysdeps/x86_64/multiarch/strcasecmp_l-avx2.S [new file with mode: 0644]
sysdeps/x86_64/multiarch/strcasecmp_l-sse2-unaligned.S [new file with mode: 0644]
sysdeps/x86_64/multiarch/strcmp-avx2.S [new file with mode: 0644]
sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S
sysdeps/x86_64/multiarch/strcmp-sse42.S [deleted file]
sysdeps/x86_64/multiarch/strcmp.S
sysdeps/x86_64/multiarch/strncase_l-avx2.S [new file with mode: 0644]
sysdeps/x86_64/multiarch/strncase_l-sse2-unaligned.S [new file with mode: 0644]
sysdeps/x86_64/multiarch/strncmp-avx2.S [new file with mode: 0644]
sysdeps/x86_64/multiarch/strncmp-sse2-unaligned.S [new file with mode: 0644]

index aebff9a4f98a4906ed04d9e7002db8509345f836..804debb6c45075643ee7b7406da9b0239c99e5c3 100644 (file)
@@ -8,4 +8,5 @@ LOCALE_T___LOCALES              offsetof (struct __locale_struct, __locales)
 LC_CTYPE
 _NL_CTYPE_NONASCII_CASE
 LOCALE_DATA_VALUES             offsetof (struct __locale_data, values)
+LOCALE_TOLOWER                 offsetof (struct __locale_struct, __ctype_tolower)
 SIZEOF_VALUES                  sizeof (((struct __locale_data *) 0)->values[0])
index 679db2a2969e9891bfed7f5fd9fe0c8acbe5cc8d..80941621ebbd1c576599c46dfc411a4228046b0c 100644 (file)
@@ -7,12 +7,13 @@ endif
 ifeq ($(subdir),string)
 
 sysdep_routines += strncat-c stpncpy-c strncpy-c strcmp-ssse3 \
-                  strcmp-sse2-unaligned strncmp-ssse3 \
+                  strcmp-sse2-unaligned strncmp-sse2-unaligned strncmp-ssse3 \
                   memcpy-ssse3 \
                   memcpy-sse2-unaligned mempcpy-ssse3 \
                   memmove-ssse3 memcpy-ssse3-back mempcpy-ssse3-back \
                   memmove-avx-unaligned memcpy-avx-unaligned mempcpy-avx-unaligned \
                   memmove-ssse3-back strcasecmp_l-ssse3 \
+                  strcasecmp_l-sse2-unaligned strncase_l-sse2-unaligned \
                   strncase_l-ssse3 strcat-ssse3 strncat-ssse3\
                   strcpy-ssse3 strncpy-ssse3 stpcpy-ssse3 stpncpy-ssse3 \
                   strcpy-sse2-unaligned strncpy-sse2-unaligned \
@@ -29,7 +30,7 @@ CFLAGS-strspn-c.c += -msse4
 endif
 
 ifeq (yes,$(config-cflags-avx2))
-sysdep_routines += memset-avx2 strcpy-avx2 stpcpy-avx2 memcmp-avx2
+sysdep_routines += memset-avx2 strcpy-avx2 stpcpy-avx2 memcmp-avx2  strcmp-avx2 strncmp-avx2 strcasecmp_l-avx2 strncase_l-avx2
 endif
 endif
 
index b3dbe65052f00a24597ece9f3b28c010a242af7e..8c71030403c173e2dfefadb4915d69512113229d 100644 (file)
@@ -94,20 +94,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/strcasecmp_l.S.  */
   IFUNC_IMPL (i, name, strcasecmp,
-             IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_AVX,
-                             __strcasecmp_avx)
-             IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_SSE4_2,
-                             __strcasecmp_sse42)
+             IFUNC_IMPL_ADD (array, i, strcasecmp, 1,
+                             __strcasecmp_sse2_unaligned)
+             IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_AVX2,
+                             __strcasecmp_avx2)
              IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_SSSE3,
                              __strcasecmp_ssse3)
              IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_sse2))
 
   /* Support sysdeps/x86_64/multiarch/strcasecmp_l.S.  */
   IFUNC_IMPL (i, name, strcasecmp_l,
-             IFUNC_IMPL_ADD (array, i, strcasecmp_l, HAS_AVX,
-                             __strcasecmp_l_avx)
-             IFUNC_IMPL_ADD (array, i, strcasecmp_l, HAS_SSE4_2,
-                             __strcasecmp_l_sse42)
+             IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
+                             __strcasecmp_sse2_unaligned_l)
              IFUNC_IMPL_ADD (array, i, strcasecmp_l, HAS_SSSE3,
                              __strcasecmp_l_ssse3)
              IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
@@ -130,7 +128,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/strcmp.S.  */
   IFUNC_IMPL (i, name, strcmp,
-             IFUNC_IMPL_ADD (array, i, strcmp, HAS_SSE4_2, __strcmp_sse42)
+             IFUNC_IMPL_ADD (array, i, strcmp, HAS_AVX2, __strcmp_avx2)
              IFUNC_IMPL_ADD (array, i, strcmp, HAS_SSSE3, __strcmp_ssse3)
              IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_sse2_unaligned)
              IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_sse2))
@@ -150,10 +148,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/strncase_l.S.  */
   IFUNC_IMPL (i, name, strncasecmp,
-             IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_AVX,
-                             __strncasecmp_avx)
-             IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_SSE4_2,
-                             __strncasecmp_sse42)
+             IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_AVX2,
+                             __strncasecmp_avx2)
+             IFUNC_IMPL_ADD (array, i, strncasecmp, 1,
+                             __strncasecmp_sse2_unaligned)
              IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_SSSE3,
                              __strncasecmp_ssse3)
              IFUNC_IMPL_ADD (array, i, strncasecmp, 1,
@@ -161,10 +159,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/strncase_l.S.  */
   IFUNC_IMPL (i, name, strncasecmp_l,
-             IFUNC_IMPL_ADD (array, i, strncasecmp_l, HAS_AVX,
-                             __strncasecmp_l_avx)
-             IFUNC_IMPL_ADD (array, i, strncasecmp_l, HAS_SSE4_2,
-                             __strncasecmp_l_sse42)
+             IFUNC_IMPL_ADD (array, i, strncasecmp_l, HAS_AVX2,
+                             __strncasecmp_avx2_l)
+             IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1,
+                             __strncasecmp_sse2_unaligned_l)
              IFUNC_IMPL_ADD (array, i, strncasecmp_l, HAS_SSSE3,
                              __strncasecmp_l_ssse3)
              IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1,
@@ -261,8 +259,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/strncmp.S.  */
   IFUNC_IMPL (i, name, strncmp,
-             IFUNC_IMPL_ADD (array, i, strncmp, HAS_SSE4_2,
-                             __strncmp_sse42)
+             IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_sse2_unaligned)
+             IFUNC_IMPL_ADD (array, i, strncmp, HAS_AVX2, __strncmp_avx2)
+
              IFUNC_IMPL_ADD (array, i, strncmp, HAS_SSSE3,
                              __strncmp_ssse3)
              IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_sse2))
diff --git a/sysdeps/x86_64/multiarch/strcasecmp_l-avx2.S b/sysdeps/x86_64/multiarch/strcasecmp_l-avx2.S
new file mode 100644 (file)
index 0000000..d10379f
--- /dev/null
@@ -0,0 +1,5 @@
+#define AS_STRCASECMP
+#define USE_AVX2
+#define __strcasecmp_sse2_unaligned __strcasecmp_avx2
+#define STRCMP __strcasecmp_avx2_l
+#include "strcmp-sse2-unaligned.S"
diff --git a/sysdeps/x86_64/multiarch/strcasecmp_l-sse2-unaligned.S b/sysdeps/x86_64/multiarch/strcasecmp_l-sse2-unaligned.S
new file mode 100644 (file)
index 0000000..e2ed03f
--- /dev/null
@@ -0,0 +1,3 @@
+#define AS_STRCASECMP
+#define STRCMP __strcasecmp_sse2_unaligned_l
+#include "strcmp-sse2-unaligned.S"
diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S
new file mode 100644 (file)
index 0000000..606df63
--- /dev/null
@@ -0,0 +1,3 @@
+#define USE_AVX2
+#define STRCMP __strcmp_avx2
+#include "strcmp-sse2-unaligned.S"
index 20b65fa77566b4447ea64ce4bd2d28a9f33e2c67..ef67fb02cd4eab0d61c6a67bfe24d3f7a9e15a8b 100644 (file)
 
 #include "sysdep.h"
 
-ENTRY ( __strcmp_sse2_unaligned)
-       movl    %edi, %eax
-       xorl    %edx, %edx
+#ifndef STRCMP
+# define STRCMP __strcmp_sse2_unaligned
+#endif
+
+#ifdef AS_STRCASECMP
+# include "locale-defines.h"
+
+# ifdef AS_STRNCMP
+ENTRY (__strncasecmp_sse2_unaligned)
+       movq    __libc_tsd_LOCALE@gottpoff(%rip), %rax
+       mov     %fs:(%rax), %rcx
+        // XXX 5 byte should be before the function
+        /* 5-byte NOP.  */
+       .byte   0x0f,0x1f,0x44,0x00,0x00
+
+END (__strncasecmp_sse2_unaligned)
+
+ENTRY (STRCMP)
+       test    %rdx, %rdx
+       je      L(ret_zero)
+       mov     LOCALE_TOLOWER(%rcx), %r11
+# else
+ENTRY (__strcasecmp_sse2_unaligned)
+       movq    __libc_tsd_LOCALE@gottpoff(%rip), %rax
+       mov     %fs:(%rax), %rdx
+        // XXX 5 byte should be before the function
+        /* 5-byte NOP.  */
+       .byte   0x0f,0x1f,0x44,0x00,0x00
+
+END (__strcasecmp_sse2_unaligned)
+
+ENTRY (STRCMP)
+       mov     LOCALE_TOLOWER(%rdx), %r11
+# endif
+       movzbl  (%rdi), %eax
+       movzbl  (%rsi), %ecx
+       movl    (%r11,%rax,4), %eax
+       subl    (%r11,%rcx,4), %eax
+       je      L(next)
+L(return):
+       ret
+L(next):
+       test    %ecx, %ecx
+       je      L(return)
+       leaq    1(%rsi), %rsi
+       leaq    1(%rdi), %rdi
+#ifdef AS_STRNCMP
+       sub     $1, %rdx
+#endif
+
+#else
+ENTRY (STRCMP)
+#endif
+
+#ifdef AS_STRNCMP
+       lea     -1(%rdx), %r10
+       test    %rdx, %rdx
+       je      L(ret_zero)
+L(back_to_start):
+       xor     %rdx, %rdx
+#endif
+
        pxor    %xmm7, %xmm7
-       orl     %esi, %eax
+       movl    %esi, %eax
+       andl    $4095, %eax
+       cmpl    $4032, %eax
+       jg      L(cross_page)
+
+       movl    %edi, %eax
        andl    $4095, %eax
        cmpl    $4032, %eax
        jg      L(cross_page)
+#ifdef AS_STRNCMP
+       cmp     $64, %r10
+       jae     L(dont_set_mask)
+       bts     %r10, %rdx
+L(dont_set_mask):
+#endif
+
        movdqu  (%rdi), %xmm1
        movdqu  (%rsi), %xmm0
        pcmpeqb %xmm1, %xmm0
        pminub  %xmm1, %xmm0
-       pxor    %xmm1, %xmm1
-       pcmpeqb %xmm1, %xmm0
-       pmovmskb        %xmm0, %eax
-       testq   %rax, %rax
+       pcmpeqb %xmm7, %xmm0
+       pmovmskb %xmm0, %ecx
+#ifdef AS_STRNCMP
+       or      %dx, %cx
+#else
+       test    %ecx, %ecx
+#endif
        je      L(next_48_bytes)
-L(return):
-       bsfq    %rax, %rdx
+#ifdef AS_STRCASECMP
+L(caseloop1):
+       bsf     %ecx, %r9d
+       movzbl  (%rdi,%r9), %eax
+       movzbl  (%rsi,%r9), %r8d
+       movl    (%r11,%rax,4), %eax
+       subl    (%r11,%r8,4), %eax
+       jne     L(return)
+       test    %r8d, %r8d
+       je      L(return)
+# ifdef AS_STRNCMP
+       cmp     %r9, %r10
+       je      L(return)
+# endif
+       leaq    -1(%rcx), %rax
+       andq    %rax, %rcx
+       je      L(next_48_bytes)
+       jmp     L(caseloop1)
+#else
+       bsf     %ecx, %edx
        movzbl  (%rdi, %rdx), %eax
        movzbl  (%rsi, %rdx), %edx
        subl    %edx, %eax
        ret
+#endif
+#ifdef AS_STRNCMP
+       L(ret_zero):
+       xor     %eax, %eax
+       ret
+#endif
 
        .p2align 4
 L(next_48_bytes):
@@ -50,49 +148,108 @@ L(next_48_bytes):
        pcmpeqb %xmm6, %xmm3
        movdqu  32(%rsi), %xmm2
        pminub  %xmm6, %xmm3
-       pcmpeqb %xmm1, %xmm3
+       pcmpeqb %xmm7, %xmm3
        movdqu  48(%rdi), %xmm4
        pcmpeqb %xmm5, %xmm2
-       pmovmskb        %xmm3, %edx
        movdqu  48(%rsi), %xmm0
        pminub  %xmm5, %xmm2
-       pcmpeqb %xmm1, %xmm2
+       pcmpeqb %xmm7, %xmm2
        pcmpeqb %xmm4, %xmm0
-       pmovmskb        %xmm2, %eax
-       salq    $16, %rdx
-       pminub  %xmm4, %xmm0
-       pcmpeqb %xmm1, %xmm0
+       pmovmskb %xmm2, %eax
        salq    $32, %rax
+#ifdef AS_STRNCMP
+       or      %rdx, %rax
+#endif
+       pmovmskb %xmm3, %edx
+       sal     $16, %edx
+       pminub  %xmm4, %xmm0
+       pcmpeqb %xmm7, %xmm0
        orq     %rdx, %rax
-       pmovmskb        %xmm0, %ecx
-       movq    %rcx, %rdx
-       salq    $48, %rdx
-       orq     %rdx, %rax
+       pmovmskb %xmm0, %ecx
+       salq    $48, %rcx
+       orq     %rax, %rcx
+       je      L(main_loop_header)
+#ifdef AS_STRCASECMP
+L(caseloop2):
+       bsf     %rcx, %r9
+       movzbl  (%rdi,%r9), %eax
+       movzbl  (%rsi,%r9), %r8d
+       movl    (%r11,%rax,4), %eax
+       subl    (%r11,%r8,4), %eax
        jne     L(return)
+       test    %r8d, %r8d
+       je      L(return)
+# ifdef AS_STRNCMP
+       cmp     %r9, %r10
+       je      L(return)
+# endif
+       leaq    -1(%rcx), %rax
+       andq    %rax, %rcx
+       je      L(main_loop_header)
+       jmp     L(caseloop2)
+#else
+       bsf     %rcx, %rdx
+       movzbl  (%rdi, %rdx), %eax
+       movzbl  (%rsi, %rdx), %edx
+       subl    %edx, %eax
+       ret
+#endif
+
 L(main_loop_header):
+#ifdef USE_AVX2
+       vpxor   %xmm7, %xmm7, %xmm7
+#endif
        leaq    64(%rdi), %rdx
-       movl    $4096, %ecx
-       pxor    %xmm9, %xmm9
        andq    $-64, %rdx
+# ifdef AS_STRNCMP
+       addq    %rdi, %r10
+       subq    %rdx, %r10
+# endif
        subq    %rdi, %rdx
        leaq    (%rdi, %rdx), %rax
        addq    %rsi, %rdx
-       movq    %rdx, %rsi
-       andl    $4095, %esi
-       subq    %rsi, %rcx
-       shrq    $6, %rcx
-       movq    %rcx, %rsi
-       jmp     L(loop_start)
+       movl    $4096, %esi
+       mov     %edx, %ecx
+       andl    $4095, %ecx
+       sub     %ecx, %esi
+       shr     $6, %esi
+#ifdef AS_STRNCMP
+       mov     %r10, %r9
+       addq    %rdx, %r10
+       shr     $6, %r9
+       cmp     %r9, %rsi
+       jb      L(dont_set_page_bound)
+       mov     %r9, %rsi
+L(dont_set_page_bound):
+#endif
 
        .p2align 4
 L(loop):
+       add     $-1, %rsi
+       ja      L(loop_cross_page)
+L(back_to_loop):
+#ifdef USE_AVX2
+       vmovdqa (%rax), %ymm4
+       vmovdqa 32(%rax), %ymm5
+       vmovdqu (%rdx), %ymm0
+       vmovdqu 32(%rdx), %ymm1
+       vpcmpeqb %ymm4, %ymm0, %ymm0
+       vpminub %ymm4, %ymm0, %ymm0
+       vpcmpeqb %ymm5, %ymm1, %ymm1
+       vpminub %ymm5, %ymm1, %ymm1
+       vpminub %ymm0, %ymm1, %ymm2
+       vpcmpeqb %ymm7, %ymm2, %ymm2
        addq    $64, %rax
        addq    $64, %rdx
-L(loop_start):
-       testq   %rsi, %rsi
-       leaq    -1(%rsi), %rsi
-       je      L(loop_cross_page)
-L(back_to_loop):
+       vpmovmskb %ymm2, %edi
+       test    %edi, %edi
+       je      L(loop)
+       shl     $32, %rdi
+       vpcmpeqb %ymm7, %ymm0, %ymm0
+       vpmovmskb %ymm0, %ecx
+       or      %rdi, %rcx
+       vzeroupper
+#else
        movdqu  (%rdx), %xmm0
        movdqu  16(%rdx), %xmm1
        movdqa  (%rax), %xmm2
@@ -104,61 +261,99 @@ L(back_to_loop):
        movdqu  48(%rdx), %xmm6
        pminub  %xmm3, %xmm1
        movdqa  32(%rax), %xmm2
-       pminub  %xmm1, %xmm0
        movdqa  48(%rax), %xmm3
        pcmpeqb %xmm2, %xmm5
        pcmpeqb %xmm3, %xmm6
+       addq    $64, %rax
        pminub  %xmm2, %xmm5
        pminub  %xmm3, %xmm6
-       pminub  %xmm5, %xmm0
-       pminub  %xmm6, %xmm0
-       pcmpeqb %xmm7, %xmm0
-       pmovmskb        %xmm0, %ecx
+       addq    $64, %rdx
+       pminub  %xmm5, %xmm6
+       pminub  %xmm1, %xmm6
+       pminub  %xmm0, %xmm6
+       pcmpeqb %xmm7, %xmm6
+       pmovmskb %xmm6, %ecx
        testl   %ecx, %ecx
        je      L(loop)
-       pcmpeqb %xmm7, %xmm5
-       movdqu  (%rdx), %xmm0
-       pcmpeqb %xmm7, %xmm1
-       movdqa  (%rax), %xmm2
-       pcmpeqb %xmm2, %xmm0
-       pminub  %xmm2, %xmm0
-       pcmpeqb %xmm7, %xmm6
        pcmpeqb %xmm7, %xmm0
-       pmovmskb        %xmm1, %ecx
-       pmovmskb        %xmm5, %r8d
-       pmovmskb        %xmm0, %edi
-       salq    $16, %rcx
+       pcmpeqb %xmm7, %xmm1
+       pcmpeqb %xmm7, %xmm5
+       pmovmskb %xmm0, %edi
+       pmovmskb %xmm1, %r9d
+       pmovmskb %xmm5, %r8d
+       salq    $48, %rcx
        salq    $32, %r8
-       pmovmskb        %xmm6, %esi
        orq     %r8, %rcx
        orq     %rdi, %rcx
-       salq    $48, %rsi
-       orq     %rsi, %rcx
+       sal     $16, %r9d
+       orq     %r9, %rcx
+#endif
+#ifdef AS_STRCASECMP
+L(caseloop3):
+       bsf     %rcx, %r9
+       movzbl  -64(%rax,%r9), %edi
+       movzbl  -64(%rdx,%r9), %r8d
+       movl    (%r11,%rdi,4), %edi
+       subl    (%r11,%r8,4), %edi
+       jne     L(return2)
+       test    %r8d, %r8d
+       je      L(return2)
+       leaq    -1(%rcx), %rdi
+       andq    %rdi, %rcx
+       je      L(loop)
+       jmp     L(caseloop3)
+L(return2):
+       mov     %rdi, %rax
+       ret
+#else
        bsfq    %rcx, %rcx
-       movzbl  (%rax, %rcx), %eax
-       movzbl  (%rdx, %rcx), %edx
+       movzbl  -64(%rax, %rcx), %eax
+       movzbl  -64(%rdx, %rcx), %edx
        subl    %edx, %eax
        ret
+#endif
 
        .p2align 4
 L(loop_cross_page):
-       xor     %r10, %r10
-       movq    %rdx, %r9
-       and     $63, %r9
-       subq    %r9, %r10
-
-       movdqa  (%rdx, %r10), %xmm0
-       movdqa  16(%rdx, %r10), %xmm1
-       movdqu  (%rax, %r10), %xmm2
-       movdqu  16(%rax, %r10), %xmm3
+#ifdef AS_STRNCMP
+       mov     %r10, %r9
+       sub     %rdx, %r9
+       cmp     $64, %r9
+       jb      L(prepare_back_to_start)
+#endif
+
+       mov     %edx, %ecx
+       and     $63, %ecx
+       neg     %rcx
+#ifdef USE_AVX2
+       vmovdqu (%rax, %rcx), %ymm4
+       vmovdqu 32(%rax, %rcx), %ymm5
+       vmovdqa (%rdx, %rcx), %ymm0
+       vmovdqa 32(%rdx, %rcx), %ymm1
+       vpcmpeqb %ymm4, %ymm0, %ymm0
+       vpminub %ymm4, %ymm0, %ymm0
+       vpcmpeqb %ymm5, %ymm1, %ymm1
+       vpminub %ymm5, %ymm1, %ymm1
+       vpminub %ymm0, %ymm1, %ymm2
+       vpcmpeqb %ymm7, %ymm2, %ymm2
+       vpmovmskb %ymm2, %esi
+       shl     $32, %rsi
+       vpcmpeqb %ymm7, %ymm0, %ymm0
+       vpmovmskb %ymm0, %edi
+       or      %rsi, %rdi
+#else
+       movdqa  (%rdx, %rcx), %xmm0
+       movdqa  16(%rdx, %rcx), %xmm1
+       movdqu  (%rax, %rcx), %xmm2
+       movdqu  16(%rax, %rcx), %xmm3
        pcmpeqb %xmm2, %xmm0
-       movdqa  32(%rdx, %r10), %xmm5
+       movdqa  32(%rdx, %rcx), %xmm5
        pcmpeqb %xmm3, %xmm1
        pminub  %xmm2, %xmm0
-       movdqa  48(%rdx, %r10), %xmm6
+       movdqa  48(%rdx, %rcx), %xmm6
        pminub  %xmm3, %xmm1
-       movdqu  32(%rax, %r10), %xmm2
-       movdqu  48(%rax, %r10), %xmm3
+       movdqu  32(%rax, %rcx), %xmm2
+       movdqu  48(%rax, %rcx), %xmm3
        pcmpeqb %xmm2, %xmm5
        pcmpeqb %xmm3, %xmm6
        pminub  %xmm2, %xmm5
@@ -169,41 +364,143 @@ L(loop_cross_page):
        pcmpeqb %xmm7, %xmm5
        pcmpeqb %xmm7, %xmm6
 
-       pmovmskb        %xmm1, %ecx
-       pmovmskb        %xmm5, %r8d
-       pmovmskb        %xmm0, %edi
-       salq    $16, %rcx
+       pmovmskb %xmm1, %ecx
+       pmovmskb %xmm5, %r8d
+       pmovmskb %xmm0, %edi
+       sal     $16, %ecx
        salq    $32, %r8
-       pmovmskb        %xmm6, %esi
+       pmovmskb %xmm6, %esi
        orq     %r8, %rdi
        orq     %rcx, %rdi
        salq    $48, %rsi
        orq     %rsi, %rdi
-       movq    %r9, %rcx
-       movq    $63, %rsi
+#endif
+       mov     %edx, %ecx
+       mov     $63, %esi
+#ifdef AS_STRNCMP
+       shr     $6, %r9
+       sub     $1, %r9
+       cmp     %r9, %rsi
+       jb      L(dont_set_bound2)
+       mov     %r9, %rsi
+L(dont_set_bound2):
+#endif
        shrq    %cl, %rdi
        test    %rdi, %rdi
        je      L(back_to_loop)
+#ifdef USE_AVX2
+       vzeroupper
+#endif
+
+#ifdef AS_STRCASECMP
+       mov     %rdi, %rcx
+L(caseloop4):
+       bsf     %rcx, %r9
+       movzbl  (%rax,%r9), %edi
+       movzbl  (%rdx,%r9), %r8d
+       movl    (%r11,%rdi,4), %edi
+       subl    (%r11,%r8,4), %edi
+       jne     L(return2)
+       test    %r8d, %r8d
+       je      L(return2)
+       leaq    -1(%rcx), %rdi
+       andq    %rdi, %rcx
+       je      L(back_to_loop)
+       jmp     L(caseloop4)
+#else
        bsfq    %rdi, %rcx
        movzbl  (%rax, %rcx), %eax
        movzbl  (%rdx, %rcx), %edx
        subl    %edx, %eax
        ret
+#endif
+#ifdef AS_STRNCMP
+L(prepare_back_to_start):
+# ifdef USE_AVX2
+       vzeroupper
+# endif
+       mov     %r9, %r10
+       mov     %rdx, %rsi
+       mov     %rax, %rdi
+       jmp     L(back_to_start)
+#endif
 
+
+L(cross_page):
+       xorl    %edx, %edx
        .p2align 4
 L(cross_page_loop):
-       cmpb    %cl, %al
-       jne     L(different)
-       addq    $1, %rdx
-       cmpq    $64, %rdx
-       je      L(main_loop_header)
-L(cross_page):
        movzbl  (%rdi, %rdx), %eax
        movzbl  (%rsi, %rdx), %ecx
-       testb   %al, %al
-       jne     L(cross_page_loop)
-       xorl    %eax, %eax
-L(different):
+#ifdef AS_STRCASECMP
+        movl    (%r11,%rax,4), %eax
+        subl    (%r11,%rcx,4), %eax
+#else
+       subl    %ecx, %eax
+#endif
+       jne     L(different)
+#ifdef AS_STRNCMP
+       cmp     %rdx, %r10
+       je      L(different)
+#endif
+       test    %ecx, %ecx
+       je      L(different)
+
+       movzbl  1(%rdi, %rdx), %eax
+       movzbl  1(%rsi, %rdx), %ecx
+#ifdef AS_STRCASECMP
+        movl    (%r11,%rax,4), %eax
+        subl    (%r11,%rcx,4), %eax
+#else
        subl    %ecx, %eax
+#endif
+       jne     L(different)
+#ifdef AS_STRNCMP
+       lea     1(%rdx), %r9
+       cmp     %r9, %r10
+       je      L(different)
+#endif
+       test    %ecx, %ecx
+       je      L(different)
+
+       movzbl  2(%rdi, %rdx), %eax
+       movzbl  2(%rsi, %rdx), %ecx
+#ifdef AS_STRCASECMP
+        movl    (%r11,%rax,4), %eax
+        subl    (%r11,%rcx,4), %eax
+#else
+       subl    %ecx, %eax
+#endif
+       jne     L(different)
+#ifdef AS_STRNCMP
+       lea     2(%rdx), %r9
+       cmp     %r9, %r10
+       je      L(different)
+#endif
+       test    %ecx, %ecx
+       je      L(different)
+
+       movzbl  3(%rdi, %rdx), %eax
+       movzbl  3(%rsi, %rdx), %ecx
+#ifdef AS_STRCASECMP
+        movl    (%r11,%rax,4), %eax
+        subl    (%r11,%rcx,4), %eax
+#else
+       subl    %ecx, %eax
+#endif
+       jne     L(different)
+#ifdef AS_STRNCMP
+       lea     3(%rdx), %r9
+       cmp     %r9, %r10
+       je      L(different)
+#endif
+       test    %ecx, %ecx
+       je      L(different)
+
+       add     $4, %edx
+       cmp     $64, %edx
+       je      L(main_loop_header)
+       jmp     L(cross_page_loop)
+L(different):
        ret
-END (__strcmp_sse2_unaligned)
+END (STRCMP)
diff --git a/sysdeps/x86_64/multiarch/strcmp-sse42.S b/sysdeps/x86_64/multiarch/strcmp-sse42.S
deleted file mode 100644 (file)
index 4dff0a5..0000000
+++ /dev/null
@@ -1,1792 +0,0 @@
-/* strcmp with SSE4.2
-   Copyright (C) 2009-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-
-/* We use 0x1a:
-       _SIDD_SBYTE_OPS
-       | _SIDD_CMP_EQUAL_EACH
-       | _SIDD_NEGATIVE_POLARITY
-       | _SIDD_LEAST_SIGNIFICANT
-   on pcmpistri to find out if two 16byte data elements are the same
-   and the offset of the first different byte.  There are 4 cases:
-
-   1. Both 16byte data elements are valid and identical.
-   2. Both 16byte data elements have EOS and identical.
-   3. Both 16byte data elements are valid and they differ at offset X.
-   4. At least one 16byte data element has EOS at offset X.  Two 16byte
-      data elements must differ at or before offset X.
-
-   Here is the table of ECX, CFlag, ZFlag and SFlag for 4 cases:
-
-   case                ECX     CFlag   ZFlag   SFlag
-    1          16        0       0       0
-    2          16        0       1       1
-    3           X        1       0       0
-    4         0 <= X     1      0/1     0/1
-
-   We exit from the loop for cases 2, 3 and 4 with jbe which branches
-   when either CFlag or ZFlag is 1.  If CFlag == 0, we return 0 for
-   case 2.  */
-
-       /* Put all SSE 4.2 functions together.  */
-       .section .text.SECTION,"ax",@progbits
-       .align  16
-       .type   STRCMP_SSE42, @function
-       .globl  STRCMP_SSE42
-       .hidden STRCMP_SSE42
-#ifdef USE_AS_STRCASECMP_L
-ENTRY (GLABEL(__strcasecmp))
-       movq    __libc_tsd_LOCALE@gottpoff(%rip),%rax
-       mov     %fs:(%rax),%RDX_LP
-
-       // XXX 5 byte should be before the function
-       /* 5-byte NOP.  */
-       .byte   0x0f,0x1f,0x44,0x00,0x00
-END (GLABEL(__strcasecmp))
-       /* FALLTHROUGH to strcasecmp_l.  */
-#endif
-#ifdef USE_AS_STRNCASECMP_L
-ENTRY (GLABEL(__strncasecmp))
-       movq    __libc_tsd_LOCALE@gottpoff(%rip),%rax
-       mov     %fs:(%rax),%RCX_LP
-
-       // XXX 5 byte should be before the function
-       /* 5-byte NOP.  */
-       .byte   0x0f,0x1f,0x44,0x00,0x00
-END (GLABEL(__strncasecmp))
-       /* FALLTHROUGH to strncasecmp_l.  */
-#endif
-
-
-#ifdef USE_AVX
-# define movdqa vmovdqa
-# define movdqu vmovdqu
-# define pmovmskb vpmovmskb
-# define pcmpistri vpcmpistri
-# define psubb vpsubb
-# define pcmpeqb vpcmpeqb
-# define psrldq vpsrldq
-# define pslldq vpslldq
-# define palignr vpalignr
-# define pxor vpxor
-# define D(arg) arg, arg
-#else
-# define D(arg) arg
-#endif
-
-STRCMP_SSE42:
-       cfi_startproc
-       CALL_MCOUNT
-
-/*
- * This implementation uses SSE to compare up to 16 bytes at a time.
- */
-#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
-       mov     LOCALE_T___LOCALES+LC_CTYPE*LP_SIZE(%rdx), %RAX_LP
-# else
-       mov     (%rdx), %RAX_LP
-# endif
-       testl   $1, 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
-       mov     LOCALE_T___LOCALES+LC_CTYPE*LP_SIZE(%rcx), %RAX_LP
-# else
-       mov     (%rcx), %RAX_LP
-# endif
-       testl   $1, 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)
-       cmp     $1, %rdx
-       je      LABEL(Byte0)
-       mov     %rdx, %r11
-#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
-LABEL(belowupper):
-       .quad   0x4040404040404040
-       .quad   0x4040404040404040
-LABEL(topupper):
-# ifdef USE_AVX
-       .quad   0x5a5a5a5a5a5a5a5a
-       .quad   0x5a5a5a5a5a5a5a5a
-# else
-       .quad   0x5b5b5b5b5b5b5b5b
-       .quad   0x5b5b5b5b5b5b5b5b
-# endif
-LABEL(touppermask):
-       .quad   0x2020202020202020
-       .quad   0x2020202020202020
-       .previous
-       movdqa  LABEL(belowupper)(%rip), %xmm4
-# define UCLOW_reg %xmm4
-       movdqa  LABEL(topupper)(%rip), %xmm5
-# define UCHIGH_reg %xmm5
-       movdqa  LABEL(touppermask)(%rip), %xmm6
-# define LCQWORD_reg %xmm6
-#endif
-       cmp     $0x30, %ecx
-       ja      LABEL(crosscache)/* rsi: 16-byte load will cross cache line */
-       cmp     $0x30, %eax
-       ja      LABEL(crosscache)/* 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
-# ifdef USE_AVX
-#  define TOLOWER(reg1, reg2) \
-       vpcmpgtb UCLOW_reg, reg1, %xmm7;                        \
-       vpcmpgtb UCHIGH_reg, reg1, %xmm8;                       \
-       vpcmpgtb UCLOW_reg, reg2, %xmm9;                        \
-       vpcmpgtb UCHIGH_reg, reg2, %xmm10;                      \
-       vpandn  %xmm7, %xmm8, %xmm8;                                    \
-       vpandn  %xmm9, %xmm10, %xmm10;                                  \
-       vpand   LCQWORD_reg, %xmm8, %xmm8;                              \
-       vpand   LCQWORD_reg, %xmm10, %xmm10;                            \
-       vpor    reg1, %xmm8, reg1;                                      \
-       vpor    reg2, %xmm10, reg2
-# else
-#  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
-# endif
-       TOLOWER (%xmm1, %xmm2)
-#else
-# define TOLOWER(reg1, reg2)
-#endif
-       pxor    %xmm0, D(%xmm0)         /* clear %xmm0 for null char checks */
-       pcmpeqb %xmm1, D(%xmm0)         /* Any null chars? */
-       pcmpeqb %xmm2, D(%xmm1)         /* compare first 16 bytes for equality */
-       psubb   %xmm0, D(%xmm1)         /* packed sub of comparison results*/
-       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 */
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)/* finish comparison */
-#endif
-       add     $16, %rsi               /* prepare to search next 16 bytes */
-       add     $16, %rdi               /* prepare to search next 16 bytes */
-
-       /*
-        * Determine source and destination string offsets from 16-byte
-        * alignment.  Use relative offset difference between the two to
-        * determine which case below to use.
-        */
-       .p2align 4
-LABEL(crosscache):
-       and     $0xfffffffffffffff0, %rsi /* force %rsi is 16 byte aligned */
-       and     $0xfffffffffffffff0, %rdi /* force %rdi is 16 byte aligned */
-       mov     $0xffff, %edx           /* for equivalent offset */
-       xor     %r8d, %r8d
-       and     $0xf, %ecx              /* offset of rsi */
-       and     $0xf, %eax              /* offset of rdi */
-       pxor    %xmm0, D(%xmm0)         /* clear %xmm0 for null char check */
-       cmp     %eax, %ecx
-       je      LABEL(ashr_0)           /* rsi and rdi relative offset same */
-       ja      LABEL(bigger)
-       mov     %edx, %r8d              /* r8d is offset flag for exit tail */
-       xchg    %ecx, %eax
-       xchg    %rsi, %rdi
-LABEL(bigger):
-       movdqa  (%rdi), %xmm2
-       movdqa  (%rsi), %xmm1
-       lea     15(%rax), %r9
-       sub     %rcx, %r9
-       lea     LABEL(unaligned_table)(%rip), %r10
-       movslq  (%r10, %r9,4), %r9
-       pcmpeqb %xmm1, D(%xmm0)         /* Any null chars? */
-       lea     (%r10, %r9), %r10
-       jmp     *%r10                   /* jump to corresponding case */
-
-/*
- * The following cases will be handled by ashr_0
- *  rcx(offset of rsi)  rax(offset of rdi)  relative offset  corresponding case
- *        n(0~15)            n(0~15)           15(15+ n-n)         ashr_0
- */
-       .p2align 4
-LABEL(ashr_0):
-
-       movdqa  (%rsi), %xmm1
-       pcmpeqb %xmm1, D(%xmm0)         /* Any null chars? */
-#if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
-       pcmpeqb (%rdi), D(%xmm1)        /* compare 16 bytes for equality */
-#else
-       movdqa  (%rdi), %xmm2
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm2, D(%xmm1)         /* compare 16 bytes for equality */
-#endif
-       psubb   %xmm0, D(%xmm1)         /* packed sub of comparison results*/
-       pmovmskb %xmm1, %r9d
-       shr     %cl, %edx               /* adjust 0xffff for offset */
-       shr     %cl, %r9d               /* adjust for 16-byte offset */
-       sub     %r9d, %edx
-       /*
-        * edx must be the same with r9d if in left byte (16-rcx) is equal to
-        * the start from (16-rax) and no null char was seen.
-        */
-       jne     LABEL(less32bytes)      /* mismatch or null char */
-       UPDATE_STRNCMP_COUNTER
-       mov     $16, %rcx
-       mov     $16, %r9
-
-       /*
-        * Now both strings are aligned at 16-byte boundary. Loop over strings
-        * checking 32-bytes per iteration.
-        */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-       .p2align 4
-LABEL(ashr_0_use):
-       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_exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#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_exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       jmp     LABEL(ashr_0_use)
-
-
-       .p2align 4
-LABEL(ashr_0_exit_use):
-       jnc     LABEL(strcmp_exitz)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     %rcx, %r11
-       jbe     LABEL(strcmp_exitz)
-#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
- *        n(15)            n -15            0(15 +(n-15) - n)         ashr_1
- */
-       .p2align 4
-LABEL(ashr_1):
-       pslldq  $15, D(%xmm2)           /* shift first string to align with second */
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)         /* compare 16 bytes for equality */
-       psubb   %xmm0, D(%xmm2)         /* packed sub of comparison results*/
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx               /* adjust 0xffff for offset */
-       shr     %cl, %r9d               /* adjust for 16-byte offset */
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)      /* mismatch or null char seen */
-       movdqa  (%rdi), %xmm3
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx               /* index for loads*/
-       mov     $1, %r9d                /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     1(%rdi), %r10
-       and     $0xfff, %r10            /* offset into 4K page */
-       sub     $0x1000, %r10           /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_1_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_1_use)
-
-LABEL(nibble_ashr_1_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $1, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_1_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $1, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_1_use)
-
-       .p2align 4
-LABEL(nibble_ashr_1_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $1, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $14, %ecx
-       ja      LABEL(nibble_ashr_1_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- * The following cases will be handled by ashr_2
- * 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
-LABEL(ashr_2):
-       pslldq  $14, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $2, %r9d        /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     2(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_2_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_2_use)
-
-LABEL(nibble_ashr_2_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $2, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_2_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $2, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_2_use)
-
-       .p2align 4
-LABEL(nibble_ashr_2_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $2, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $13, %ecx
-       ja      LABEL(nibble_ashr_2_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- * The following cases will be handled by ashr_3
- *  rcx(offset of rsi)  rax(offset of rdi)  relative offset     corresponding case
- *        n(13~15)            n -13         2(15 +(n-13) - n)         ashr_3
- */
-       .p2align 4
-LABEL(ashr_3):
-       pslldq  $13, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $3, %r9d        /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     3(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-LABEL(loop_ashr_3_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_3_use)
-
-LABEL(nibble_ashr_3_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $3, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_3_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $3, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_3_use)
-
-       .p2align 4
-LABEL(nibble_ashr_3_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $3, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $12, %ecx
-       ja      LABEL(nibble_ashr_3_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- * The following cases will be handled by ashr_4
- *  rcx(offset of rsi)  rax(offset of rdi)  relative offset     corresponding case
- *        n(12~15)            n -12         3(15 +(n-12) - n)         ashr_4
- */
-       .p2align 4
-LABEL(ashr_4):
-       pslldq  $12, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $4, %r9d        /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     4(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_4_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_4_use)
-
-LABEL(nibble_ashr_4_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $4, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_4_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $4, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_4_use)
-
-       .p2align 4
-LABEL(nibble_ashr_4_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $4, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $11, %ecx
-       ja      LABEL(nibble_ashr_4_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- * 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
- */
-       .p2align 4
-LABEL(ashr_5):
-       pslldq  $11, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $5, %r9d        /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     5(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_5_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_5_use)
-
-LABEL(nibble_ashr_5_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $5, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_5_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-
-       palignr $5, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_5_use)
-
-       .p2align 4
-LABEL(nibble_ashr_5_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $5, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $10, %ecx
-       ja      LABEL(nibble_ashr_5_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- * 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
- */
-       .p2align 4
-LABEL(ashr_6):
-       pslldq  $10, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $6, %r9d        /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     6(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_6_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_6_use)
-
-LABEL(nibble_ashr_6_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $6, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_6_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $6, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_6_use)
-
-       .p2align 4
-LABEL(nibble_ashr_6_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $6, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $9, %ecx
-       ja      LABEL(nibble_ashr_6_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- * 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
- */
-       .p2align 4
-LABEL(ashr_7):
-       pslldq  $9, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $7, %r9d        /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     7(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_7_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_7_use)
-
-LABEL(nibble_ashr_7_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $7, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_7_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $7, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_7_use)
-
-       .p2align 4
-LABEL(nibble_ashr_7_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $7, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $8, %ecx
-       ja      LABEL(nibble_ashr_7_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- *  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
- */
-       .p2align 4
-LABEL(ashr_8):
-       pslldq  $8, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $8, %r9d        /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     8(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_8_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_8_use)
-
-LABEL(nibble_ashr_8_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $8, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_8_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $8, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_8_use)
-
-       .p2align 4
-LABEL(nibble_ashr_8_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $8, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $7, %ecx
-       ja      LABEL(nibble_ashr_8_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- *  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
- */
-       .p2align 4
-LABEL(ashr_9):
-       pslldq  $7, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $9, %r9d        /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     9(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_9_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_9_use)
-
-LABEL(nibble_ashr_9_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-
-       palignr $9, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_9_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $9, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_9_use)
-
-       .p2align 4
-LABEL(nibble_ashr_9_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $9, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $6, %ecx
-       ja      LABEL(nibble_ashr_9_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- *  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
- */
-       .p2align 4
-LABEL(ashr_10):
-       pslldq  $6, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $10, %r9d       /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     10(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_10_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_10_use)
-
-LABEL(nibble_ashr_10_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $10, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_10_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $10, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_10_use)
-
-       .p2align 4
-LABEL(nibble_ashr_10_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $10, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $5, %ecx
-       ja      LABEL(nibble_ashr_10_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- *  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
- */
-       .p2align 4
-LABEL(ashr_11):
-       pslldq  $5, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $11, %r9d       /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     11(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_11_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_11_use)
-
-LABEL(nibble_ashr_11_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $11, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_11_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $11, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_11_use)
-
-       .p2align 4
-LABEL(nibble_ashr_11_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $11, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $4, %ecx
-       ja      LABEL(nibble_ashr_11_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- *  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
- */
-       .p2align 4
-LABEL(ashr_12):
-       pslldq  $4, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $12, %r9d       /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     12(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_12_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_12_use)
-
-LABEL(nibble_ashr_12_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $12, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_12_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $12, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_12_use)
-
-       .p2align 4
-LABEL(nibble_ashr_12_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $12, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $3, %ecx
-       ja      LABEL(nibble_ashr_12_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- *  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
- */
-       .p2align 4
-LABEL(ashr_13):
-       pslldq  $3, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $13, %r9d       /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     13(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_13_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_13_use)
-
-LABEL(nibble_ashr_13_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $13, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_13_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $13, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_13_use)
-
-       .p2align 4
-LABEL(nibble_ashr_13_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $13, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $2, %ecx
-       ja      LABEL(nibble_ashr_13_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- *  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
- */
-       .p2align 4
-LABEL(ashr_14):
-       pslldq  $2, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $14, %r9d       /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     14(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_14_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_14_use)
-
-LABEL(nibble_ashr_14_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $14, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_14_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $14, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_14_use)
-
-       .p2align 4
-LABEL(nibble_ashr_14_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $14, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $1, %ecx
-       ja      LABEL(nibble_ashr_14_restart_use)
-
-       jmp     LABEL(nibble_ashr_exit_use)
-
-/*
- *  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
- */
-       .p2align 4
-LABEL(ashr_15):
-       pslldq  $1, D(%xmm2)
-       TOLOWER (%xmm1, %xmm2)
-       pcmpeqb %xmm1, D(%xmm2)
-       psubb   %xmm0, D(%xmm2)
-       pmovmskb %xmm2, %r9d
-       shr     %cl, %edx
-       shr     %cl, %r9d
-       sub     %r9d, %edx
-       jnz     LABEL(less32bytes)
-
-       movdqa  (%rdi), %xmm3
-
-       UPDATE_STRNCMP_COUNTER
-
-       mov     $16, %rcx       /* index for loads */
-       mov     $15, %r9d       /* byte position left over from less32bytes case */
-       /*
-        * Setup %r10 value allows us to detect crossing a page boundary.
-        * When %r10 goes positive we have crossed a page boundary and
-        * need to do a nibble.
-        */
-       lea     15(%rdi), %r10
-       and     $0xfff, %r10    /* offset into 4K page */
-
-       sub     $0x1000, %r10   /* subtract 4K pagesize */
-
-       mov     %rcx, %rdx      /* only for offset of sse4 instruction loop*/
-
-       .p2align 4
-LABEL(loop_ashr_15_use):
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_15_use)
-
-LABEL(nibble_ashr_15_restart_use):
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $15, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-
-       add     $16, %rdx
-       add     $16, %r10
-       jg      LABEL(nibble_ashr_15_use)
-
-       movdqa  (%rdi, %rdx), %xmm0
-       palignr $15, -16(%rdi, %rdx), D(%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(exit_use)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     $16, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     $16, %rdx
-       jmp     LABEL(loop_ashr_15_use)
-
-       .p2align 4
-LABEL(nibble_ashr_15_use):
-       sub     $0x1000, %r10
-       movdqa  -16(%rdi, %rdx), %xmm0
-       psrldq  $15, D(%xmm0)
-       pcmpistri      $0x3a,%xmm0, %xmm0
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       cmp     %r11, %rcx
-       jae     LABEL(nibble_ashr_exit_use)
-#endif
-       cmp     $0, %ecx
-       ja      LABEL(nibble_ashr_15_restart_use)
-
-LABEL(nibble_ashr_exit_use):
-#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(exit_use):
-       jnc     LABEL(strcmp_exitz)
-#if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-       sub     %rcx, %r11
-       jbe     LABEL(strcmp_exitz)
-#endif
-       add     %rcx, %rdx
-       lea     -16(%rdi, %r9), %rdi
-       movzbl  (%rdi, %rdx), %eax
-       movzbl  (%rsi, %rdx), %edx
-       test    %r8d, %r8d
-       jz      LABEL(ret_use)
-       xchg    %eax, %edx
-LABEL(ret_use):
-#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
-
-LABEL(less32bytes):
-       lea     (%rdi, %rax), %rdi      /* locate the exact address for first operand(rdi) */
-       lea     (%rsi, %rcx), %rsi      /* locate the exact address for second operand(rsi) */
-       test    %r8d, %r8d
-       jz      LABEL(ret)
-       xchg    %rsi, %rdi              /* recover original order according to flag(%r8d) */
-
-       .p2align 4
-LABEL(ret):
-LABEL(less16bytes):
-       bsf     %rdx, %rdx              /* find and store bit index in %rdx */
-
-#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
-
-LABEL(strcmp_exitz):
-       xor     %eax, %eax
-       ret
-
-       .p2align 4
-       // XXX Same as code above
-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
-       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.SECTION,"a",@progbits
-       .p2align 3
-LABEL(unaligned_table):
-       .int    LABEL(ashr_1) - LABEL(unaligned_table)
-       .int    LABEL(ashr_2) - LABEL(unaligned_table)
-       .int    LABEL(ashr_3) - LABEL(unaligned_table)
-       .int    LABEL(ashr_4) - LABEL(unaligned_table)
-       .int    LABEL(ashr_5) - LABEL(unaligned_table)
-       .int    LABEL(ashr_6) - LABEL(unaligned_table)
-       .int    LABEL(ashr_7) - LABEL(unaligned_table)
-       .int    LABEL(ashr_8) - LABEL(unaligned_table)
-       .int    LABEL(ashr_9) - LABEL(unaligned_table)
-       .int    LABEL(ashr_10) - LABEL(unaligned_table)
-       .int    LABEL(ashr_11) - LABEL(unaligned_table)
-       .int    LABEL(ashr_12) - LABEL(unaligned_table)
-       .int    LABEL(ashr_13) - LABEL(unaligned_table)
-       .int    LABEL(ashr_14) - LABEL(unaligned_table)
-       .int    LABEL(ashr_15) - LABEL(unaligned_table)
-       .int    LABEL(ashr_0) - LABEL(unaligned_table)
-
-#undef LABEL
-#undef GLABEL
-#undef SECTION
-#undef movdqa
-#undef movdqu
-#undef pmovmskb
-#undef pcmpistri
-#undef psubb
-#undef pcmpeqb
-#undef psrldq
-#undef pslldq
-#undef palignr
-#undef pxor
-#undef D
index f50f26c393f2f3bbec9db7927947d7c9e48dff9f..63aa62eb94d7228c86ea6b1b19b4896785e2b3be 100644 (file)
@@ -31,8 +31,8 @@
        test    %r9, %r9;                               \
        je      LABEL(strcmp_exitz);                    \
        mov     %r9, %r11
-
-# define STRCMP_SSE42  __strncmp_sse42
+# define STRCMP_AVX2   __strncmp_avx2
+# define STRCMP_SSE2_UNALIGNED __strncmp_sse2_unaligned
 # define STRCMP_SSSE3  __strncmp_ssse3
 # define STRCMP_SSE2   __strncmp_sse2
 # define __GI_STRCMP   __GI_strncmp
@@ -40,9 +40,8 @@
 # include "locale-defines.h"
 
 # define UPDATE_STRNCMP_COUNTER
-
-# define STRCMP_AVX    __strcasecmp_l_avx
-# define STRCMP_SSE42  __strcasecmp_l_sse42
+# define STRCMP_AVX2   __strcasecmp_avx2_l
+# define STRCMP_SSE2_UNALIGNED __strcasecmp_sse2_unaligned_l
 # define STRCMP_SSSE3  __strcasecmp_l_ssse3
 # define STRCMP_SSE2   __strcasecmp_l_sse2
 # define __GI_STRCMP   __GI___strcasecmp_l
@@ -60,8 +59,8 @@
        je      LABEL(strcmp_exitz);                    \
        mov     %r9, %r11
 
-# define STRCMP_AVX    __strncasecmp_l_avx
-# define STRCMP_SSE42  __strncasecmp_l_sse42
+# define STRCMP_AVX2   __strncasecmp_avx2_l
+# define STRCMP_SSE2_UNALIGNED __strncasecmp_sse2_unaligned_l
 # define STRCMP_SSSE3  __strncasecmp_l_ssse3
 # define STRCMP_SSE2   __strncasecmp_l_sse2
 # define __GI_STRCMP   __GI___strncasecmp_l
@@ -69,8 +68,9 @@
 # define USE_AS_STRCMP
 # define UPDATE_STRNCMP_COUNTER
 # ifndef STRCMP
+#  define STRCMP_AVX2  __strcmp_avx2
+#  define STRCMP_SSE2_UNALIGNED        __strcmp_sse2_unaligned
 #  define STRCMP       strcmp
-#  define STRCMP_SSE42 __strcmp_sse42
 #  define STRCMP_SSSE3 __strcmp_ssse3
 #  define STRCMP_SSE2  __strcmp_sse2
 #  define __GI_STRCMP  __GI_strcmp
@@ -89,17 +89,16 @@ ENTRY(STRCMP)
        jne     1f
        call    __init_cpu_features
 1:
-#ifdef USE_AS_STRCMP
-       leaq    __strcmp_sse2_unaligned(%rip), %rax
+#  ifdef HAVE_AVX2_SUPPORT
+
+        leaq    STRCMP_AVX2(%rip), %rax
+        testl   $bit_AVX_Fast_Unaligned_Load, __cpu_features+FEATURE_OFFSET+index_AVX_Fast_Unaligned_Load(%rip)
+       jnz     3f
+#  endif
+       leaq    STRCMP_SSE2_UNALIGNED(%rip), %rax
        testl   $bit_Fast_Unaligned_Load, __cpu_features+FEATURE_OFFSET+index_Fast_Unaligned_Load(%rip)
        jnz     3f
-#else
-       testl   $bit_Slow_SSE4_2, __cpu_features+FEATURE_OFFSET+index_Slow_SSE4_2(%rip)
-       jnz     2f
-       leaq    STRCMP_SSE42(%rip), %rax
-       testl   $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip)
-       jnz     3f
-#endif
+
 2:     leaq    STRCMP_SSSE3(%rip), %rax
        testl   $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip)
        jnz     3f
@@ -115,21 +114,22 @@ ENTRY(__strcasecmp)
        jne     1f
        call    __init_cpu_features
 1:
-#  ifdef HAVE_AVX_SUPPORT
-       leaq    __strcasecmp_avx(%rip), %rax
-       testl   $bit_AVX_Usable, __cpu_features+FEATURE_OFFSET+index_AVX_Usable(%rip)
+#  ifdef HAVE_AVX2_SUPPORT
+
+        leaq    __strcasecmp_avx2(%rip), %rax
+        testl   $bit_AVX_Fast_Unaligned_Load, __cpu_features+FEATURE_OFFSET+index_AVX_Fast_Unaligned_Load(%rip)
        jnz     3f
 #  endif
-       testl   $bit_Slow_SSE4_2, __cpu_features+FEATURE_OFFSET+index_Slow_SSE4_2(%rip)
-       jnz     2f
-       leaq    __strcasecmp_sse42(%rip), %rax
-       testl   $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip)
-       jnz     3f
+       leaq    __strcasecmp_sse2_unaligned(%rip), %rax
+       testl   $bit_Fast_Unaligned_Load, __cpu_features+FEATURE_OFFSET+index_Fast_Unaligned_Load(%rip)
+       jnz     3f
+
 2:     leaq    __strcasecmp_ssse3(%rip), %rax
        testl   $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip)
        jnz     3f
        leaq    __strcasecmp_sse2(%rip), %rax
 3:     ret
+
 END(__strcasecmp)
 weak_alias (__strcasecmp, strcasecmp)
 # endif
@@ -141,45 +141,26 @@ ENTRY(__strncasecmp)
        jne     1f
        call    __init_cpu_features
 1:
-#  ifdef HAVE_AVX_SUPPORT
-       leaq    __strncasecmp_avx(%rip), %rax
-       testl   $bit_AVX_Usable, __cpu_features+FEATURE_OFFSET+index_AVX_Usable(%rip)
+#  ifdef HAVE_AVX2_SUPPORT
+
+        leaq    __strncasecmp_avx2(%rip), %rax
+        testl   $bit_AVX_Fast_Unaligned_Load, __cpu_features+FEATURE_OFFSET+index_AVX_Fast_Unaligned_Load(%rip)
        jnz     3f
 #  endif
-       testl   $bit_Slow_SSE4_2, __cpu_features+FEATURE_OFFSET+index_Slow_SSE4_2(%rip)
-       jnz     2f
-       leaq    __strncasecmp_sse42(%rip), %rax
-       testl   $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip)
-       jnz     3f
+       leaq    __strncasecmp_sse2_unaligned(%rip), %rax
+       testl   $bit_Fast_Unaligned_Load, __cpu_features+FEATURE_OFFSET+index_Fast_Unaligned_Load(%rip)
+       jnz     3f
+
 2:     leaq    __strncasecmp_ssse3(%rip), %rax
        testl   $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip)
        jnz     3f
        leaq    __strncasecmp_sse2(%rip), %rax
 3:     ret
+
 END(__strncasecmp)
 weak_alias (__strncasecmp, strncasecmp)
 # endif
 
-# undef LABEL
-# define LABEL(l) .L##l##_sse42
-# define GLABEL(l) l##_sse42
-# define SECTION sse4.2
-# include "strcmp-sse42.S"
-
-
-# ifdef HAVE_AVX_SUPPORT
-#  if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
-#   define LABEL(l) .L##l##_avx
-#   define GLABEL(l) l##_avx
-#   define USE_AVX 1
-#   undef STRCMP_SSE42
-#   define STRCMP_SSE42 STRCMP_AVX
-#   define SECTION avx
-#   include "strcmp-sse42.S"
-#  endif
-# endif
-
-
 # undef ENTRY
 # define ENTRY(name) \
        .type STRCMP_SSE2, @function; \
diff --git a/sysdeps/x86_64/multiarch/strncase_l-avx2.S b/sysdeps/x86_64/multiarch/strncase_l-avx2.S
new file mode 100644 (file)
index 0000000..809b966
--- /dev/null
@@ -0,0 +1,6 @@
+#define AS_STRCASECMP
+#define AS_STRNCMP
+#define USE_AVX2
+#define __strncasecmp_sse2_unaligned __strncasecmp_avx2
+#define STRCMP __strncasecmp_avx2_l
+#include "strcmp-sse2-unaligned.S"
diff --git a/sysdeps/x86_64/multiarch/strncase_l-sse2-unaligned.S b/sysdeps/x86_64/multiarch/strncase_l-sse2-unaligned.S
new file mode 100644 (file)
index 0000000..a372ed4
--- /dev/null
@@ -0,0 +1,4 @@
+#define AS_STRCASECMP
+#define AS_STRNCMP
+#define STRCMP __strncasecmp_sse2_unaligned_l
+#include "strcmp-sse2-unaligned.S"
diff --git a/sysdeps/x86_64/multiarch/strncmp-avx2.S b/sysdeps/x86_64/multiarch/strncmp-avx2.S
new file mode 100644 (file)
index 0000000..2d9a032
--- /dev/null
@@ -0,0 +1,4 @@
+#define USE_AVX2
+#define AS_STRNCMP
+#define STRCMP __strncmp_avx2
+#include "strcmp-sse2-unaligned.S"
diff --git a/sysdeps/x86_64/multiarch/strncmp-sse2-unaligned.S b/sysdeps/x86_64/multiarch/strncmp-sse2-unaligned.S
new file mode 100644 (file)
index 0000000..7f9a5fd
--- /dev/null
@@ -0,0 +1,3 @@
+#define AS_STRNCMP
+#define STRCMP __strncmp_sse2_unaligned
+#include "strcmp-sse2-unaligned.S"