diff options
author | Ulrich Drepper <drepper@redhat.com> | 2010-08-14 22:04:01 -0700 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2010-08-14 22:04:01 -0700 |
commit | e9f82e0d1d70f361a40f1853c928df04918a38f5 (patch) | |
tree | cdbf94a494dc32833a600e6c86b776b59d646bd7 /sysdeps/x86_64/strcmp.S | |
parent | ca6bb004ebd1cc7da72f1a761ffea377245d1ee9 (diff) | |
download | glibc-e9f82e0d1d70f361a40f1853c928df04918a38f5.tar.gz glibc-e9f82e0d1d70f361a40f1853c928df04918a38f5.tar.xz glibc-e9f82e0d1d70f361a40f1853c928df04918a38f5.zip |
Add optimized strncasecmp versions for x86-64.
Diffstat (limited to 'sysdeps/x86_64/strcmp.S')
-rw-r--r-- | sysdeps/x86_64/strcmp.S | 169 |
1 files changed, 110 insertions, 59 deletions
diff --git a/sysdeps/x86_64/strcmp.S b/sysdeps/x86_64/strcmp.S index 1b48f04172..5a4346be05 100644 --- a/sysdeps/x86_64/strcmp.S +++ b/sysdeps/x86_64/strcmp.S @@ -60,10 +60,26 @@ # endif # define UPDATE_STRNCMP_COUNTER +#elif defined USE_AS_STRNCASECMP_L +# include "locale-defines.h" + +/* No support for strncasecmp outside libc so far since it is not needed. */ +# ifdef NOT_IN_lib +# error "strncasecmp_l not implemented so far" +# endif + +# define UPDATE_STRNCMP_COUNTER \ + /* calculate left number to compare */ \ + lea -16(%rcx, %r11), %r9; \ + cmp %r9, %r11; \ + jb LABEL(strcmp_exitz); \ + test %r9, %r9; \ + je LABEL(strcmp_exitz); \ + mov %r9, %r11 #else # define UPDATE_STRNCMP_COUNTER # ifndef STRCMP -# define STRCMP strcmp +# define STRCMP strncasecmp # endif #endif @@ -79,7 +95,7 @@ # define END2(name) END (name) # endif - ENTRY2 (__strcasecmp) +ENTRY2 (__strcasecmp) movq __libc_tsd_LOCALE@gottpoff(%rip),%rax movq %fs:(%rax),%rdx @@ -92,6 +108,25 @@ weak_alias (__strcasecmp, strcasecmp) libc_hidden_def (__strcasecmp) # endif /* FALLTHROUGH to strcasecmp_l. */ +#elif defined USE_AS_STRNCASECMP_L +# ifndef ENTRY2 +# define ENTRY2(name) ENTRY (name) +# define END2(name) END (name) +# endif + +ENTRY2 (__strncasecmp) + movq __libc_tsd_LOCALE@gottpoff(%rip),%rax + movq %fs:(%rax),%r10 + + // XXX 5 byte should be before the function + /* 5-byte NOP. */ + .byte 0x0f,0x1f,0x44,0x00,0x00 +END2 (__strncasecmp) +# ifndef NO_NOLOCALE_ALIAS +weak_alias (__strncasecmp, strncasecmp) +libc_hidden_def (__strncasecmp) +# endif + /* FALLTHROUGH to strncasecmp_l. */ #endif ENTRY (BP_SYM (STRCMP)) @@ -124,12 +159,22 @@ END (BP_SYM (STRCMP)) # endif testl $0, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%rax) jne __strcasecmp_l_nonascii +# elif defined USE_AS_STRNCASECMP_L + /* We have to fall back on the C implementation for locales + with encodings not matching ASCII for single bytes. */ +# if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0 + movq LOCALE_T___LOCALES+LC_CTYPE*8(%r10), %rax +# else + movq (%r10), %rax +# endif + testl $0, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%rax) + jne __strncasecmp_l_nonascii # endif /* * This implementation uses SSE to compare up to 16 bytes at a time. */ -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L test %rdx, %rdx je LABEL(strcmp_exitz) cmp $1, %rdx @@ -141,7 +186,7 @@ END (BP_SYM (STRCMP)) /* Use 64bit AND here to avoid long NOP padding. */ and $0x3f, %rcx /* rsi alignment in cache line */ and $0x3f, %rax /* rdi alignment in cache line */ -# ifdef USE_AS_STRCASECMP_L +# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L .section .rodata.cst16,"aM",@progbits,16 .align 16 .Lbelowupper: @@ -155,11 +200,11 @@ END (BP_SYM (STRCMP)) .quad 0x2020202020202020 .previous movdqa .Lbelowupper(%rip), %xmm5 -# define UCLOW_reg %xmm5 +# define UCLOW_reg %xmm5 movdqa .Ltopupper(%rip), %xmm6 -# define UCHIGH_reg %xmm6 +# define UCHIGH_reg %xmm6 movdqa .Ltouppermask(%rip), %xmm7 -# define LCQWORD_reg %xmm7 +# define LCQWORD_reg %xmm7 # endif cmp $0x30, %ecx ja LABEL(crosscache) /* rsi: 16-byte load will cross cache line */ @@ -169,7 +214,7 @@ END (BP_SYM (STRCMP)) movlpd (%rsi), %xmm2 movhpd 8(%rdi), %xmm1 movhpd 8(%rsi), %xmm2 -# ifdef USE_AS_STRCASECMP_L +# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L # define TOLOWER(reg1, reg2) \ movdqa reg1, %xmm8; \ movdqa UCHIGH_reg, %xmm9; \ @@ -196,7 +241,7 @@ END (BP_SYM (STRCMP)) pmovmskb %xmm1, %edx sub $0xffff, %edx /* if first 16 bytes are same, edx == 0xffff */ jnz LABEL(less16bytes) /* If not, find different value or null char */ -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) /* finish comparision */ # endif @@ -241,7 +286,7 @@ LABEL(ashr_0): movdqa (%rsi), %xmm1 pxor %xmm0, %xmm0 /* clear %xmm0 for null char check */ pcmpeqb %xmm1, %xmm0 /* Any null chars? */ -# ifndef USE_AS_STRCASECMP_L +# if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L pcmpeqb (%rdi), %xmm1 /* compare 16 bytes for equality */ # else movdqa (%rdi), %xmm2 @@ -280,7 +325,7 @@ LABEL(loop_ashr_0): sub $0xffff, %edx jnz LABEL(exit) /* mismatch or null char seen */ -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -295,7 +340,7 @@ LABEL(loop_ashr_0): pmovmskb %xmm1, %edx sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -363,7 +408,7 @@ LABEL(gobble_ashr_1): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -393,7 +438,7 @@ LABEL(gobble_ashr_1): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -412,7 +457,7 @@ LABEL(nibble_ashr_1): test $0xfffe, %edx jnz LABEL(ashr_1_exittail) /* find null char*/ -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $14, %r11 jbe LABEL(ashr_1_exittail) # endif @@ -493,7 +538,7 @@ LABEL(gobble_ashr_2): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -524,7 +569,7 @@ LABEL(gobble_ashr_2): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -540,7 +585,7 @@ LABEL(nibble_ashr_2): test $0xfffc, %edx jnz LABEL(ashr_2_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $13, %r11 jbe LABEL(ashr_2_exittail) # endif @@ -618,7 +663,7 @@ LABEL(gobble_ashr_3): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -649,7 +694,7 @@ LABEL(gobble_ashr_3): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -665,7 +710,7 @@ LABEL(nibble_ashr_3): test $0xfff8, %edx jnz LABEL(ashr_3_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $12, %r11 jbe LABEL(ashr_3_exittail) # endif @@ -743,7 +788,7 @@ LABEL(gobble_ashr_4): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -774,7 +819,7 @@ LABEL(gobble_ashr_4): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -790,7 +835,7 @@ LABEL(nibble_ashr_4): test $0xfff0, %edx jnz LABEL(ashr_4_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $11, %r11 jbe LABEL(ashr_4_exittail) # endif @@ -868,7 +913,7 @@ LABEL(gobble_ashr_5): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -899,7 +944,7 @@ LABEL(gobble_ashr_5): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -915,7 +960,7 @@ LABEL(nibble_ashr_5): test $0xffe0, %edx jnz LABEL(ashr_5_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $10, %r11 jbe LABEL(ashr_5_exittail) # endif @@ -993,7 +1038,7 @@ LABEL(gobble_ashr_6): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1024,7 +1069,7 @@ LABEL(gobble_ashr_6): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1040,7 +1085,7 @@ LABEL(nibble_ashr_6): test $0xffc0, %edx jnz LABEL(ashr_6_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $9, %r11 jbe LABEL(ashr_6_exittail) # endif @@ -1118,7 +1163,7 @@ LABEL(gobble_ashr_7): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1149,7 +1194,7 @@ LABEL(gobble_ashr_7): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1165,7 +1210,7 @@ LABEL(nibble_ashr_7): test $0xff80, %edx jnz LABEL(ashr_7_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $8, %r11 jbe LABEL(ashr_7_exittail) # endif @@ -1243,7 +1288,7 @@ LABEL(gobble_ashr_8): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1274,7 +1319,7 @@ LABEL(gobble_ashr_8): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1290,7 +1335,7 @@ LABEL(nibble_ashr_8): test $0xff00, %edx jnz LABEL(ashr_8_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $7, %r11 jbe LABEL(ashr_8_exittail) # endif @@ -1368,7 +1413,7 @@ LABEL(gobble_ashr_9): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1399,7 +1444,7 @@ LABEL(gobble_ashr_9): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1415,7 +1460,7 @@ LABEL(nibble_ashr_9): test $0xfe00, %edx jnz LABEL(ashr_9_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $6, %r11 jbe LABEL(ashr_9_exittail) # endif @@ -1493,7 +1538,7 @@ LABEL(gobble_ashr_10): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1524,7 +1569,7 @@ LABEL(gobble_ashr_10): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1540,7 +1585,7 @@ LABEL(nibble_ashr_10): test $0xfc00, %edx jnz LABEL(ashr_10_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $5, %r11 jbe LABEL(ashr_10_exittail) # endif @@ -1618,7 +1663,7 @@ LABEL(gobble_ashr_11): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1649,7 +1694,7 @@ LABEL(gobble_ashr_11): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1665,7 +1710,7 @@ LABEL(nibble_ashr_11): test $0xf800, %edx jnz LABEL(ashr_11_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $4, %r11 jbe LABEL(ashr_11_exittail) # endif @@ -1743,7 +1788,7 @@ LABEL(gobble_ashr_12): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1774,7 +1819,7 @@ LABEL(gobble_ashr_12): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1790,7 +1835,7 @@ LABEL(nibble_ashr_12): test $0xf000, %edx jnz LABEL(ashr_12_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $3, %r11 jbe LABEL(ashr_12_exittail) # endif @@ -1868,7 +1913,7 @@ LABEL(gobble_ashr_13): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1899,7 +1944,7 @@ LABEL(gobble_ashr_13): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -1915,7 +1960,7 @@ LABEL(nibble_ashr_13): test $0xe000, %edx jnz LABEL(ashr_13_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $2, %r11 jbe LABEL(ashr_13_exittail) # endif @@ -1993,7 +2038,7 @@ LABEL(gobble_ashr_14): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -2024,7 +2069,7 @@ LABEL(gobble_ashr_14): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP | defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -2040,7 +2085,7 @@ LABEL(nibble_ashr_14): test $0xc000, %edx jnz LABEL(ashr_14_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L cmp $1, %r11 jbe LABEL(ashr_14_exittail) # endif @@ -2120,7 +2165,7 @@ LABEL(gobble_ashr_15): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -2151,7 +2196,7 @@ LABEL(gobble_ashr_15): sub $0xffff, %edx jnz LABEL(exit) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub $16, %r11 jbe LABEL(strcmp_exitz) # endif @@ -2167,7 +2212,7 @@ LABEL(nibble_ashr_15): test $0x8000, %edx jnz LABEL(ashr_15_exittail) -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L test %r11, %r11 je LABEL(ashr_15_exittail) # endif @@ -2205,14 +2250,14 @@ LABEL(ret): LABEL(less16bytes): bsf %rdx, %rdx /* find and store bit index in %rdx */ -# ifdef USE_AS_STRNCMP +# if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L sub %rdx, %r11 jbe LABEL(strcmp_exitz) # endif movzbl (%rsi, %rdx), %ecx movzbl (%rdi, %rdx), %eax -# ifdef USE_AS_STRCASECMP_L +# 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 @@ -2230,6 +2275,12 @@ LABEL(Byte0): movzx (%rsi), %ecx movzx (%rdi), %eax +# if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L + leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx + movl (%rdx,%rcx,4), %ecx + movl (%rdx,%rax,4), %eax +# endif + sub %ecx, %eax ret END (BP_SYM (STRCMP)) |