2 Copyright (C) 2010-2021 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 <https://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 adjustment. */
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 adjustment. */
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 movl %gs:(%eax), %eax
106 movl %gs:__libc_tsd_LOCALE@NTPOFF, %eax
108 # if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
109 movl LOCALE_T___LOCALES+LC_CTYPE*4(%eax), %eax
113 testl $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax)
117 jmp __strcasecmp_nonascii
119 jne __strcasecmp_nonascii
122 END (__strcasecmp_sse4_2)
125 #ifdef USE_AS_STRNCASECMP_L
126 ENTRY (__strncasecmp_sse4_2)
130 movl __libc_tsd_LOCALE@GOTNTPOFF(%ebx), %eax
131 movl %gs:(%eax), %eax
133 movl %gs:__libc_tsd_LOCALE@NTPOFF, %eax
135 # if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
136 movl LOCALE_T___LOCALES+LC_CTYPE*4(%eax), %eax
140 testl $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax)
144 jmp __strncasecmp_nonascii
146 jne __strncasecmp_nonascii
149 END (__strncasecmp_sse4_2)
153 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
154 movl LOCALE(%esp), %eax
155 # if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
156 movl LOCALE_T___LOCALES+LC_CTYPE*4(%eax), %eax
160 testl $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax)
168 .section .rodata.cst16,"aM",@progbits,16
171 .quad 0x4040404040404040
172 .quad 0x4040404040404040
174 .quad 0x5b5b5b5b5b5b5b5b
175 .quad 0x5b5b5b5b5b5b5b5b
177 .quad 0x2020202020202020
178 .quad 0x2020202020202020
182 # define UCLOW_reg .Lbelowupper@GOTOFF(%ebx)
183 # define UCHIGH_reg .Ltopupper@GOTOFF(%ebx)
184 # define LCQWORD_reg .Ltouppermask@GOTOFF(%ebx)
186 # define UCLOW_reg .Lbelowupper
187 # define UCHIGH_reg .Ltopupper
188 # define LCQWORD_reg .Ltouppermask
192 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
195 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
200 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
214 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
215 # define TOLOWER(reg1, reg2) \
216 movdqa reg1, %xmm3; \
217 movdqa UCHIGH_reg, %xmm4; \
218 movdqa reg2, %xmm5; \
219 movdqa UCHIGH_reg, %xmm6; \
220 pcmpgtb UCLOW_reg, %xmm3; \
221 pcmpgtb reg1, %xmm4; \
222 pcmpgtb UCLOW_reg, %xmm5; \
223 pcmpgtb reg2, %xmm6; \
226 pand LCQWORD_reg, %xmm3; \
227 pand LCQWORD_reg, %xmm5; \
232 TOLOWER (%xmm2, %xmm1)
239 # define TOLOWER(reg1, reg)
245 #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
256 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
264 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
267 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
268 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
270 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
271 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
281 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
287 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
290 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
291 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
293 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
294 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
304 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
309 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
312 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
313 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
315 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
316 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
326 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
331 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
334 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
335 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
337 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
338 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
348 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
353 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
356 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
357 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
359 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
360 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
370 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
375 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
378 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
379 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
381 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
382 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
392 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
397 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
400 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
401 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
403 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
404 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
414 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
419 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
422 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
423 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
425 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
426 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
436 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
443 #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
447 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
460 lea -0xff0(%ecx), %edx
466 movdqu (%esi,%edx), %xmm2
467 movdqu (%edi,%edx), %xmm1
468 TOLOWER (%xmm2, %xmm1)
469 pcmpistri $0x1a, %xmm2, %xmm1
472 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
480 movzbl (%edi,%edx), %eax
481 movzbl (%esi,%edx), %ecx
482 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
484 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%eax,4), %eax
485 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
487 movl _nl_C_LC_CTYPE_tolower+128*4(,%eax,4), %eax
488 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
495 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
509 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
513 lea (%ecx,%edx), %ecx
514 movzbl (%edi,%ecx), %eax
515 movzbl (%esi,%ecx), %ecx
516 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
518 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%eax,4), %eax
519 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
521 movl _nl_C_LC_CTYPE_tolower+128*4(,%eax,4), %eax
522 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
529 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
532 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
540 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
544 # ifdef USE_AS_STRNCMP
560 add $0xfefefeff, %ecx
562 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
572 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
576 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
588 add $0xfefefeff, %ecx
590 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
599 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
609 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
612 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
613 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
615 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
616 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
626 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
631 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
634 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
635 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
637 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
638 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
648 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
654 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
657 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
658 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
660 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
661 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
671 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
676 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
679 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
680 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
682 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
683 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
694 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
699 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
702 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
703 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
705 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
706 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
717 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
722 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
725 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
726 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
728 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
729 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
739 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
744 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
747 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
748 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
750 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
751 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
761 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
766 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
769 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx
770 movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi
772 movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
773 movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi