# define STRCMP_SSSE3 __strncmp_ssse3
# define STRCMP_SSE2 __strncmp_sse2
# define __GI_STRCMP __GI_strncmp
+#elif defined USE_AS_STRCASECMP_L
+# include "locale-defines.h"
+
+# define UPDATE_STRNCMP_COUNTER
+
+# define STRCMP_SSE42 __strcasecmp_l_sse42
+# define STRCMP_SSSE3 __strcasecmp_l_ssse3
+# define STRCMP_SSE2 __strcasecmp_l_sse2
+# define __GI_STRCMP __GI___strcasecmp_l
#else
# define UPDATE_STRNCMP_COUNTER
# ifndef STRCMP
2: ret
END(STRCMP)
+# ifdef USE_AS_STRCASECMP_L
+ENTRY(__strcasecmp)
+ .type __strcasecmp, @gnu_indirect_function
+ cmpl $0, __cpu_features+KIND_OFFSET(%rip)
+ jne 1f
+ call __init_cpu_features
+1:
+ leaq __strcasecmp_sse42(%rip), %rax
+ testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip)
+ jnz 2f
+ leaq __strcasecmp_ssse3(%rip), %rax
+ testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip)
+ jnz 2f
+ leaq __strcasecmp_sse2(%rip), %rax
+2: ret
+END(__strcasecmp)
+weak_alias (__strcasecmp, strcasecmp)
+# endif
+
/* We use 0x1a:
_SIDD_SBYTE_OPS
| _SIDD_CMP_EQUAL_EACH
.section .text.sse4.2,"ax",@progbits
.align 16
.type STRCMP_SSE42, @function
+#ifdef USE_AS_STRCASECMP_L
+ /* 5-byte NOP. */
+ .byte 0x0f,0x1f,0x44,0x00,0x00
+ENTRY (__strcasecmp_sse42)
+ movq __libc_tsd_LOCALE@gottpoff(%rip),%rax
+ movq %fs:(%rax),%rdx
+END (__strcasecmp_sse42)
+ /* FALLTHROUGH to strcasecmp_l. */
+#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
+ movq LOCALE_T___LOCALES+LC_CTYPE*8(%rdx), %rax
+# else
+ movq (%rdx), %rax
+# endif
+ testl $0, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%rax)
+ jne __strcasecmp_l_nonascii
+#endif
+
#ifdef USE_AS_STRNCMP
test %rdx, %rdx
je LABEL(strcmp_exitz_sse4_2)
/* 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 */
+#ifdef USE_AS_STRCASECMP_L
+ .section .rodata.cst16,"aM",@progbits,16
+ .align 16
+.Lbelowupper_sse4:
+ .quad 0x4040404040404040
+ .quad 0x4040404040404040
+.Ltopupper_sse4:
+ .quad 0x5b5b5b5b5b5b5b5b
+ .quad 0x5b5b5b5b5b5b5b5b
+.Ltouppermask_sse4:
+ .quad 0x2020202020202020
+ .quad 0x2020202020202020
+ .previous
+ movdqa .Lbelowupper_sse4(%rip), %xmm4
+# define UCLOW_reg %xmm4
+ movdqa .Ltopupper_sse4(%rip), %xmm5
+# define UCHIGH_reg %xmm5
+ movdqa .Ltouppermask_sse4(%rip), %xmm6
+# define LCQWORD_reg %xmm6
+#endif
cmp $0x30, %ecx
ja LABEL(crosscache_sse4_2)/* rsi: 16-byte load will cross cache line */
cmp $0x30, %eax
ja LABEL(crosscache_sse4_2)/* rdi: 16-byte load will cross cache line */
movdqu (%rdi), %xmm1
movdqu (%rsi), %xmm2
+# ifdef USE_AS_STRCASECMP_L
+# define TOLOWER(reg1, reg2) \
+ movdqa reg1, %xmm7; \
+ movdqa UCHIGH_reg, %xmm8; \
+ movdqa reg2, %xmm9; \
+ movdqa UCHIGH_reg, %xmm10; \
+ pcmpgtb UCLOW_reg, %xmm7; \
+ pcmpgtb reg1, %xmm8; \
+ pcmpgtb UCLOW_reg, %xmm9; \
+ pcmpgtb reg2, %xmm10; \
+ pand %xmm8, %xmm7; \
+ pand %xmm10, %xmm9; \
+ pand LCQWORD_reg, %xmm7; \
+ pand LCQWORD_reg, %xmm9; \
+ por %xmm7, reg1; \
+ por %xmm9, reg2
+ TOLOWER (%xmm1, %xmm2)
+# else
+# define TOLOWER(reg1, reg2)
+# endif
pxor %xmm0, %xmm0 /* clear %xmm0 for null char checks */
pcmpeqb %xmm1, %xmm0 /* Any null chars? */
pcmpeqb %xmm2, %xmm1 /* compare first 16 bytes for equality */
movdqa (%rsi), %xmm1
pxor %xmm0, %xmm0 /* clear %xmm0 for null char check */
pcmpeqb %xmm1, %xmm0 /* Any null chars? */
+#ifndef USE_AS_STRCASECMP_L
pcmpeqb (%rdi), %xmm1 /* compare 16 bytes for equality */
+#else
+ movdqa (%rdi), %xmm2
+ TOLOWER (%xmm1, %xmm2)
+ pcmpeqb %xmm2, %xmm1 /* compare 16 bytes for equality */
+#endif
psubb %xmm0, %xmm1 /* packed sub of comparison results*/
pmovmskb %xmm1, %r9d
shr %cl, %edx /* adjust 0xffff for offset */
.p2align 4
LABEL(ashr_0_use_sse4_2):
movdqa (%rdi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
lea 16(%rdx), %rdx
jbe LABEL(ashr_0_use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
#endif
movdqa (%rdi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
lea 16(%rdx), %rdx
jbe LABEL(ashr_0_use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
lea -16(%rdx, %rcx), %rcx
movzbl (%rdi, %rcx), %eax
movzbl (%rsi, %rcx), %edx
+# ifdef USE_AS_STRCASECMP_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
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0 /* Any null chars? */
pslldq $15, %xmm2 /* shift first string to align with second */
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2 /* compare 16 bytes for equality */
psubb %xmm0, %xmm2 /* packed sub of comparison results*/
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $1, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $1, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $14, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $2, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $2, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $13, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $3, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $3, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $12, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $4, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $4, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $11, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $5, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $5, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $10, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $6, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $6, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $9, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $7, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $7, -16(%rdi, %rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $8, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $8, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $8, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $7, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $9, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $9, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $6, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $10, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $10, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $5, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $11, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $11, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $4, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $12, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $12, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $3, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $13, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $13, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $2, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $14, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $14, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rsi), %xmm1
pcmpeqb %xmm1, %xmm0
pslldq $1, %xmm2
+ TOLOWER (%xmm1, %xmm2)
pcmpeqb %xmm1, %xmm2
psubb %xmm0, %xmm2
pmovmskb %xmm2, %r9d
movdqa (%rdi, %rdx), %xmm0
palignr $15, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
movdqa (%rdi, %rdx), %xmm0
palignr $15, -16(%rdi, %rdx), %xmm0
- pcmpistri $0x1a,(%rsi,%rdx), %xmm0
+#ifndef USE_AS_STRCASECMP_L
+ pcmpistri $0x1a, (%rsi,%rdx), %xmm0
+#else
+ movdqa (%rsi,%rdx), %xmm1
+ TOLOWER (%xmm0, %xmm1)
+ pcmpistri $0x1a, %xmm1, %xmm0
+#endif
jbe LABEL(use_sse4_2_exit)
#ifdef USE_AS_STRNCMP
sub $16, %r11
jz LABEL(use_sse4_2_ret_sse4_2)
xchg %eax, %edx
LABEL(use_sse4_2_ret_sse4_2):
+# ifdef USE_AS_STRCASECMP_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
movzbl (%rsi, %rdx), %ecx
movzbl (%rdi, %rdx), %eax
+# ifdef USE_AS_STRCASECMP_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
ret
.p2align 4
+ // XXX Same as code above
LABEL(Byte0_sse4_2):
movzx (%rsi), %ecx
movzx (%rdi), %eax
+# ifdef USE_AS_STRCASECMP_L
+ leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx
+ movl (%rdx,%rcx,4), %ecx
+ movl (%rdx,%rax,4), %eax
+# endif
+
sub %ecx, %eax
ret
cfi_endproc
.size STRCMP_SSE42, .-STRCMP_SSE42
+# undef UCLOW_reg
+# undef UCHIGH_reg
+# undef LCQWORD_reg
+# undef TOLOWER
+
/* Put all SSE 4.2 functions together. */
.section .rodata.sse4.2,"a",@progbits
.p2align 3
# undef END
# define END(name) \
cfi_endproc; .size STRCMP_SSE2, .-STRCMP_SSE2
+
+# ifdef USE_AS_STRCASECMP_L
+# define ENTRY2(name) \
+ .type __strcasecmp_sse2, @function; \
+ .align 16; \
+ __strcasecmp_sse2: cfi_startproc; \
+ CALL_MCOUNT
+# define END2(name) \
+ cfi_endproc; .size __strcasecmp_sse2, .-__strcasecmp_sse2
+# endif
+
# undef libc_hidden_builtin_def
/* It doesn't make sense to send libc-internal strcmp calls through a PLT.
The speedup we get from using SSE4.2 instruction is likely eaten away