2 Copyright (C) 2010-2013 Free Software Foundation, Inc.
3 Contributed by Intel Corporation.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
23 #include "asm-syntax.h"
25 #define CFI_PUSH(REG) \
26 cfi_adjust_cfa_offset (4); \
27 cfi_rel_offset (REG, 0)
29 #define CFI_POP(REG) \
30 cfi_adjust_cfa_offset (-4); \
33 #define PUSH(REG) pushl REG; CFI_PUSH (REG)
34 #define POP(REG) popl REG; CFI_POP (REG)
38 # define STRCMP __strncmp_sse4_2
43 # define RETURN POP (REM); ret; .p2align 4; CFI_PUSH (REM)
45 #elif defined USE_AS_STRCASECMP_L
46 # include "locale-defines.h"
48 # define STRCMP __strcasecmp_l_sse4_2
56 # define LOCALE 12 /* Loaded before the adjustement. */
58 # define RETURN POP (%edi); POP (%ebx); ret; \
59 .p2align 4; CFI_PUSH (%ebx); CFI_PUSH (%edi)
61 # define RETURN POP (%edi); ret; .p2align 4; CFI_PUSH (%edi)
63 # define NONASCII __strcasecmp_nonascii
64 #elif defined USE_AS_STRNCASECMP_L
65 # include "locale-defines.h"
67 # define STRCMP __strncasecmp_l_sse4_2
76 # define LOCALE 16 /* Loaded before the adjustement. */
78 # define RETURN POP (%edi); POP (REM); POP (%ebx); ret; \
80 CFI_PUSH (%ebx); CFI_PUSH (REM); CFI_PUSH (%edi)
82 # define RETURN POP (%edi); POP (REM); ret; \
83 .p2align 4; CFI_PUSH (REM); CFI_PUSH (%edi)
86 # define NONASCII __strncasecmp_nonascii
89 # define STRCMP __strcmp_sse4_2
93 # define RETURN ret; .p2align 4
96 .section .text.sse4.2,"ax",@progbits
98 #ifdef USE_AS_STRCASECMP_L
99 ENTRY (__strcasecmp_sse4_2)
103 movl __libc_tsd_LOCALE@GOTNTPOFF(%ebx), %eax
104 # ifdef NO_TLS_DIRECT_SEG_REFS
108 movl %gs:(%eax), %eax
111 # ifdef NO_TLS_DIRECT_SEG_REFS
113 movl __libc_tsd_LOCALE@NTPOFF(%eax), %eax
115 movl %gs:__libc_tsd_LOCALE@NTPOFF, %eax
118 # if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
119 movl LOCALE_T___LOCALES+LC_CTYPE*4(%eax), %eax
123 testl $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax)
124 jne __strcasecmp_nonascii
126 END (__strcasecmp_sse4_2)
129 #ifdef USE_AS_STRNCASECMP_L
130 ENTRY (__strncasecmp_sse4_2)
134 movl __libc_tsd_LOCALE@GOTNTPOFF(%ebx), %eax
135 # ifdef NO_TLS_DIRECT_SEG_REFS
139 movl %gs:(%eax), %eax
142 # ifdef NO_TLS_DIRECT_SEG_REFS
144 movl __libc_tsd_LOCALE@NTPOFF(%eax), %eax
146 movl %gs:__libc_tsd_LOCALE@NTPOFF, %eax
149 # if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
150 movl LOCALE_T___LOCALES+LC_CTYPE*4(%eax), %eax
154 testl $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax)
155 jne __strncasecmp_nonascii
157 END (__strncasecmp_sse4_2)
161 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
162 movl LOCALE(%esp), %eax
163 # if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
164 movl LOCALE_T___LOCALES+LC_CTYPE*4(%eax), %eax
168 testl $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax)
176 .section .rodata.cst16,"aM",@progbits,16
179 .quad 0x4040404040404040
180 .quad 0x4040404040404040
182 .quad 0x5b5b5b5b5b5b5b5b
183 .quad 0x5b5b5b5b5b5b5b5b
185 .quad 0x2020202020202020
186 .quad 0x2020202020202020
190 # define UCLOW_reg .Lbelowupper@GOTOFF(%ebx)
191 # define UCHIGH_reg .Ltopupper@GOTOFF(%ebx)
192 # define LCQWORD_reg .Ltouppermask@GOTOFF(%ebx)
194 # define UCLOW_reg .Lbelowupper
195 # define UCHIGH_reg .Ltopupper
196 # define LCQWORD_reg .Ltouppermask
200 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
203 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
208 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
222 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
223 # define TOLOWER(reg1, reg2) \
224 movdqa reg1, %xmm3; \
225 movdqa UCHIGH_reg, %xmm4; \
226 movdqa reg2, %xmm5; \
227 movdqa UCHIGH_reg, %xmm6; \
228 pcmpgtb UCLOW_reg, %xmm3; \
229 pcmpgtb reg1, %xmm4; \
230 pcmpgtb UCLOW_reg, %xmm5; \
231 pcmpgtb reg2, %xmm6; \
234 pand LCQWORD_reg, %xmm3; \
235 pand LCQWORD_reg, %xmm5; \
240 TOLOWER (%xmm2, %xmm1)
247 # define TOLOWER(reg1, reg)
253 #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
264 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
272 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
275 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
276 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
278 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
279 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
289 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
295 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
298 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
299 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
301 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
302 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
312 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
317 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
320 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
321 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
323 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
324 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
334 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
339 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
342 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
343 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
345 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
346 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
356 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
361 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
364 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
365 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
367 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
368 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
378 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
383 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
386 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
387 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
389 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
390 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
400 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
405 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
408 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
409 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
411 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
412 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
422 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
427 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
430 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
431 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
433 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
434 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
444 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
451 #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
455 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
468 lea -0xff0(%ecx), %edx
474 movdqu (%esi,%edx), %xmm2
475 movdqu (%edi,%edx), %xmm1
476 TOLOWER (%xmm2, %xmm1)
477 pcmpistri $0x1a, %xmm2, %xmm1
480 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
488 movzbl (%edi,%edx), %eax
489 movzbl (%esi,%edx), %ecx
490 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
492 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%eax,4), %eax
493 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
495 movl _nl_C_LC_CTYPE_tolower+128*4(,%eax,4), %eax
496 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
503 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
517 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
521 lea (%ecx,%edx), %ecx
522 movzbl (%edi,%ecx), %eax
523 movzbl (%esi,%ecx), %ecx
524 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
526 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%eax,4), %eax
527 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
529 movl _nl_C_LC_CTYPE_tolower+128*4(,%eax,4), %eax
530 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
537 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
540 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
548 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
552 # ifdef USE_AS_STRNCMP
568 add $0xfefefeff, %ecx
570 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
580 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
584 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
596 add $0xfefefeff, %ecx
598 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
607 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
617 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
620 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
621 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
623 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
624 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
634 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
639 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
642 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
643 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
645 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
646 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
656 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
662 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
665 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
666 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
668 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
669 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
679 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
684 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
687 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
688 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
690 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
691 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
702 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
707 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
710 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
711 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
713 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
714 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
725 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
730 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
733 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
734 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
736 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
737 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
747 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
752 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
755 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
756 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
758 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
759 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
769 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
774 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
777 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
778 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
780 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
781 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi