Update copyright notices with scripts/update-copyrights.
[jlayton/glibc.git] / sysdeps / i386 / i686 / multiarch / strcmp-sse4.S
1 /* strcmp with SSE4.2
2    Copyright (C) 2010-2013 Free Software Foundation, Inc.
3    Contributed by Intel Corporation.
4    This file is part of the GNU C Library.
5
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.
10
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.
15
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/>.  */
19
20 #ifndef NOT_IN_libc
21
22 #include <sysdep.h>
23 #include "asm-syntax.h"
24
25 #define CFI_PUSH(REG)                                           \
26   cfi_adjust_cfa_offset (4);                                    \
27   cfi_rel_offset (REG, 0)
28
29 #define CFI_POP(REG)                                            \
30   cfi_adjust_cfa_offset (-4);                                   \
31   cfi_restore (REG)
32
33 #define PUSH(REG)       pushl REG; CFI_PUSH (REG)
34 #define POP(REG)        popl REG; CFI_POP (REG)
35
36 #ifdef USE_AS_STRNCMP
37 # ifndef STRCMP
38 #  define STRCMP        __strncmp_sse4_2
39 # endif
40 # define STR1           8
41 # define STR2           STR1+4
42 # define CNT            STR2+4
43 # define RETURN         POP (REM); ret; .p2align 4; CFI_PUSH (REM)
44 # define REM            %ebp
45 #elif defined USE_AS_STRCASECMP_L
46 # include "locale-defines.h"
47 # ifndef STRCMP
48 #  define STRCMP        __strcasecmp_l_sse4_2
49 # endif
50 # ifdef PIC
51 #  define STR1          12
52 # else
53 #  define STR1          8
54 # endif
55 # define STR2           STR1+4
56 # define LOCALE         12      /* Loaded before the adjustement.  */
57 # ifdef PIC
58 #  define RETURN        POP (%edi); POP (%ebx); ret; \
59                         .p2align 4; CFI_PUSH (%ebx); CFI_PUSH (%edi)
60 # else
61 #  define RETURN        POP (%edi); ret; .p2align 4; CFI_PUSH (%edi)
62 # endif
63 # define NONASCII       __strcasecmp_nonascii
64 #elif defined USE_AS_STRNCASECMP_L
65 # include "locale-defines.h"
66 # ifndef STRCMP
67 #  define STRCMP        __strncasecmp_l_sse4_2
68 # endif
69 # ifdef PIC
70 #  define STR1          16
71 # else
72 #  define STR1          12
73 # endif
74 # define STR2           STR1+4
75 # define CNT            STR2+4
76 # define LOCALE         16      /* Loaded before the adjustement.  */
77 # ifdef PIC
78 #  define RETURN        POP (%edi); POP (REM); POP (%ebx); ret; \
79                         .p2align 4; \
80                         CFI_PUSH (%ebx); CFI_PUSH (REM); CFI_PUSH (%edi)
81 # else
82 #  define RETURN        POP (%edi); POP (REM); ret; \
83                         .p2align 4; CFI_PUSH (REM); CFI_PUSH (%edi)
84 # endif
85 # define REM            %ebp
86 # define NONASCII       __strncasecmp_nonascii
87 #else
88 # ifndef STRCMP
89 #  define STRCMP        __strcmp_sse4_2
90 # endif
91 # define STR1           4
92 # define STR2           STR1+4
93 # define RETURN         ret; .p2align 4
94 #endif
95
96         .section .text.sse4.2,"ax",@progbits
97
98 #ifdef USE_AS_STRCASECMP_L
99 ENTRY (__strcasecmp_sse4_2)
100 # ifdef PIC
101         PUSH    (%ebx)
102         LOAD_PIC_REG(bx)
103         movl    __libc_tsd_LOCALE@GOTNTPOFF(%ebx), %eax
104 #  ifdef NO_TLS_DIRECT_SEG_REFS
105         addl    %gs:0, %eax
106         movl    (%eax), %eax
107 #  else
108         movl    %gs:(%eax), %eax
109 #  endif
110 # else
111 #  ifdef NO_TLS_DIRECT_SEG_REFS
112         movl    %gs:0, %eax
113         movl    __libc_tsd_LOCALE@NTPOFF(%eax), %eax
114 #  else
115         movl    %gs:__libc_tsd_LOCALE@NTPOFF, %eax
116 #  endif
117 # endif
118 # if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
119         movl    LOCALE_T___LOCALES+LC_CTYPE*4(%eax), %eax
120 # else
121         movl    (%eax), %eax
122 # endif
123         testl   $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax)
124         jne     __strcasecmp_nonascii
125         jmp     L(ascii)
126 END (__strcasecmp_sse4_2)
127 #endif
128
129 #ifdef USE_AS_STRNCASECMP_L
130 ENTRY (__strncasecmp_sse4_2)
131 # ifdef PIC
132         PUSH    (%ebx)
133         LOAD_PIC_REG(bx)
134         movl    __libc_tsd_LOCALE@GOTNTPOFF(%ebx), %eax
135 #  ifdef NO_TLS_DIRECT_SEG_REFS
136         addl    %gs:0, %eax
137         movl    (%eax), %eax
138 #  else
139         movl    %gs:(%eax), %eax
140 #  endif
141 # else
142 #  ifdef NO_TLS_DIRECT_SEG_REFS
143         movl    %gs:0, %eax
144         movl    __libc_tsd_LOCALE@NTPOFF(%eax), %eax
145 #  else
146         movl    %gs:__libc_tsd_LOCALE@NTPOFF, %eax
147 #  endif
148 # endif
149 # if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0
150         movl    LOCALE_T___LOCALES+LC_CTYPE*4(%eax), %eax
151 # else
152         movl    (%eax), %eax
153 # endif
154         testl   $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax)
155         jne     __strncasecmp_nonascii
156         jmp     L(ascii)
157 END (__strncasecmp_sse4_2)
158 #endif
159
160         ENTRY (STRCMP)
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
165 # else
166         movl    (%eax), %eax
167 # endif
168         testl   $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax)
169         jne     NONASCII
170
171 # ifdef PIC
172         PUSH    (%ebx)
173         LOAD_PIC_REG(bx)
174 # endif
175 L(ascii):
176         .section .rodata.cst16,"aM",@progbits,16
177         .align 16
178 .Lbelowupper:
179         .quad   0x4040404040404040
180         .quad   0x4040404040404040
181 .Ltopupper:
182         .quad   0x5b5b5b5b5b5b5b5b
183         .quad   0x5b5b5b5b5b5b5b5b
184 .Ltouppermask:
185         .quad   0x2020202020202020
186         .quad   0x2020202020202020
187         .previous
188
189 # ifdef PIC
190 #  define UCLOW_reg .Lbelowupper@GOTOFF(%ebx)
191 #  define UCHIGH_reg .Ltopupper@GOTOFF(%ebx)
192 #  define LCQWORD_reg .Ltouppermask@GOTOFF(%ebx)
193 # else
194 #  define UCLOW_reg .Lbelowupper
195 #  define UCHIGH_reg .Ltopupper
196 #  define LCQWORD_reg .Ltouppermask
197 # endif
198 #endif
199
200 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
201         PUSH    (REM)
202 #endif
203 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
204         PUSH    (%edi)
205 #endif
206         mov     STR1(%esp), %edx
207         mov     STR2(%esp), %eax
208 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
209         movl    CNT(%esp), REM
210         test    REM, REM
211         je      L(eq)
212 #endif
213         mov     %dx, %cx
214         and     $0xfff, %cx
215         cmp     $0xff0, %cx
216         ja      L(first4bytes)
217         movdqu  (%edx), %xmm2
218         mov     %eax, %ecx
219         and     $0xfff, %ecx
220         cmp     $0xff0, %ecx
221         ja      L(first4bytes)
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;                                                  \
232         pand    %xmm4, %xmm3;                                                 \
233         pand    %xmm6, %xmm5;                                                 \
234         pand    LCQWORD_reg, %xmm3;                                           \
235         pand    LCQWORD_reg, %xmm5;                                           \
236         por     %xmm3, reg1;                                                  \
237         por     %xmm5, reg2
238
239         movdqu  (%eax), %xmm1
240         TOLOWER (%xmm2, %xmm1)
241         movd    %xmm2, %ecx
242         movd    %xmm1, %edi
243         movdqa  %xmm2, %xmm3
244         movdqa  %xmm1, %xmm4
245         cmpl    %edi, %ecx
246 #else
247 # define TOLOWER(reg1, reg)
248
249         movd    %xmm2, %ecx
250         cmp     (%eax), %ecx
251 #endif
252         jne     L(less4bytes)
253 #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
254         movdqu  (%eax), %xmm1
255 #endif
256         pxor    %xmm2, %xmm1
257         pxor    %xmm0, %xmm0
258         ptest   %xmm1, %xmm0
259         jnc     L(less16bytes)
260         pcmpeqb %xmm0, %xmm2
261         ptest   %xmm2, %xmm0
262         jnc     L(less16bytes)
263
264 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
265         sub     $16, REM
266         jbe     L(eq)
267 #endif
268         add     $16, %edx
269         add     $16, %eax
270 L(first4bytes):
271         movzbl  (%eax), %ecx
272 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
273         movzbl  (%edx), %edi
274 # ifdef PIC
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
277 # else
278         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
279         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
280 # endif
281         cmpl    %ecx, %edi
282 #else
283         cmpb    %cl, (%edx)
284 #endif
285         jne     L(neq)
286         cmpl    $0, %ecx
287         je      L(eq)
288
289 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
290         cmp     $1, REM
291         je      L(eq)
292 #endif
293
294         movzbl  1(%eax), %ecx
295 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
296         movzbl  1(%edx), %edi
297 # ifdef PIC
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
300 # else
301         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
302         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
303 # endif
304         cmpl    %ecx, %edi
305 #else
306         cmpb    %cl, 1(%edx)
307 #endif
308         jne     L(neq)
309         cmpl    $0, %ecx
310         je      L(eq)
311
312 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
313         cmp     $2, REM
314         je      L(eq)
315 #endif
316         movzbl  2(%eax), %ecx
317 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
318         movzbl  2(%edx), %edi
319 # ifdef PIC
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
322 # else
323         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
324         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
325 # endif
326         cmpl    %ecx, %edi
327 #else
328         cmpb    %cl, 2(%edx)
329 #endif
330         jne     L(neq)
331         cmpl    $0, %ecx
332         je      L(eq)
333
334 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
335         cmp     $3, REM
336         je      L(eq)
337 #endif
338         movzbl  3(%eax), %ecx
339 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
340         movzbl  3(%edx), %edi
341 # ifdef PIC
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
344 # else
345         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
346         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
347 # endif
348         cmpl    %ecx, %edi
349 #else
350         cmpb    %cl, 3(%edx)
351 #endif
352         jne     L(neq)
353         cmpl    $0, %ecx
354         je      L(eq)
355
356 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
357         cmp     $4, REM
358         je      L(eq)
359 #endif
360         movzbl  4(%eax), %ecx
361 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
362         movzbl  4(%edx), %edi
363 # ifdef PIC
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
366 # else
367         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
368         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
369 # endif
370         cmpl    %ecx, %edi
371 #else
372         cmpb    %cl, 4(%edx)
373 #endif
374         jne     L(neq)
375         cmpl    $0, %ecx
376         je      L(eq)
377
378 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
379         cmp     $5, REM
380         je      L(eq)
381 #endif
382         movzbl  5(%eax), %ecx
383 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
384         movzbl  5(%edx), %edi
385 # ifdef PIC
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
388 # else
389         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
390         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
391 # endif
392         cmpl    %ecx, %edi
393 #else
394         cmpb    %cl, 5(%edx)
395 #endif
396         jne     L(neq)
397         cmpl    $0, %ecx
398         je      L(eq)
399
400 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
401         cmp     $6, REM
402         je      L(eq)
403 #endif
404         movzbl  6(%eax), %ecx
405 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
406         movzbl  6(%edx), %edi
407 # ifdef PIC
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
410 # else
411         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
412         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
413 # endif
414         cmpl    %ecx, %edi
415 #else
416         cmpb    %cl, 6(%edx)
417 #endif
418         jne     L(neq)
419         cmpl    $0, %ecx
420         je      L(eq)
421
422 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
423         cmp     $7, REM
424         je      L(eq)
425 #endif
426         movzbl  7(%eax), %ecx
427 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
428         movzbl  7(%edx), %edi
429 # ifdef PIC
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
432 # else
433         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
434         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
435 # endif
436         cmpl    %ecx, %edi
437 #else
438         cmpb    %cl, 7(%edx)
439 #endif
440         jne     L(neq)
441         cmpl    $0, %ecx
442         je      L(eq)
443
444 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
445         sub     $8, REM
446         je      L(eq)
447 #endif
448         add     $8, %eax
449         add     $8, %edx
450
451 #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L
452         PUSH    (%edi)
453 #endif
454         PUSH    (%esi)
455 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
456         cfi_remember_state
457 #endif
458         mov     %edx, %edi
459         mov     %eax, %esi
460         xorl    %eax, %eax
461 L(check_offset):
462         movl    %edi, %edx
463         movl    %esi, %ecx
464         andl    $0xfff, %edx
465         andl    $0xfff, %ecx
466         cmpl    %edx, %ecx
467         cmovl   %edx, %ecx
468         lea     -0xff0(%ecx), %edx
469         sub     %edx, %edi
470         sub     %edx, %esi
471         testl   %edx, %edx
472         jg      L(crosspage)
473 L(loop):
474         movdqu  (%esi,%edx), %xmm2
475         movdqu  (%edi,%edx), %xmm1
476         TOLOWER (%xmm2, %xmm1)
477         pcmpistri       $0x1a, %xmm2, %xmm1
478         jbe     L(end)
479
480 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
481         sub     $16, REM
482         jbe     L(more16byteseq)
483 #endif
484
485         add     $16, %edx
486         jle     L(loop)
487 L(crosspage):
488         movzbl  (%edi,%edx), %eax
489         movzbl  (%esi,%edx), %ecx
490 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
491 # ifdef PIC
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
494 # else
495         movl    _nl_C_LC_CTYPE_tolower+128*4(,%eax,4), %eax
496         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
497 # endif
498 #endif
499         subl    %ecx, %eax
500         jne     L(ret)
501         testl   %ecx, %ecx
502         je      L(ret)
503 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
504         sub     $1, REM
505         jbe     L(more16byteseq)
506 #endif
507         inc     %edx
508         cmp     $15, %edx
509         jle     L(crosspage)
510         add     %edx, %edi
511         add     %edx, %esi
512         jmp     L(check_offset)
513
514         .p2align 4
515 L(end):
516         jnc     L(ret)
517 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
518         sub     %ecx, REM
519         jbe     L(more16byteseq)
520 #endif
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
525 # ifdef PIC
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
528 # else
529         movl    _nl_C_LC_CTYPE_tolower+128*4(,%eax,4), %eax
530         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
531 # endif
532 #endif
533         subl    %ecx, %eax
534 L(ret):
535         POP     (%esi)
536         POP     (%edi)
537 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
538         POP     (REM)
539 #endif
540 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
541 # ifdef PIC
542         POP     (%ebx)
543 # endif
544 #endif
545         ret
546
547         .p2align 4
548 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
549         cfi_restore_state
550 L(more16byteseq):
551         POP     (%esi)
552 # ifdef USE_AS_STRNCMP
553         POP     (%edi)
554 # endif
555 #endif
556 L(eq):
557         xorl    %eax, %eax
558         RETURN
559
560 L(neq):
561         mov     $1, %eax
562         ja      L(neq_bigger)
563         neg     %eax
564 L(neq_bigger):
565         RETURN
566
567 L(less16bytes):
568         add     $0xfefefeff, %ecx
569         jnc     L(less4bytes)
570 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
571         movd    %xmm3, %edi
572         xor     %edi, %ecx
573 #else
574         xor     (%edx), %ecx
575 #endif
576         or      $0xfefefeff, %ecx
577         add     $1, %ecx
578         jnz     L(less4bytes)
579
580 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
581         cmp     $4, REM
582         jbe     L(eq)
583 #endif
584 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
585         psrldq  $4, %xmm3
586         psrldq  $4, %xmm4
587         movd    %xmm3, %ecx
588         movd    %xmm4, %edi
589         cmp     %edi, %ecx
590         mov     %ecx, %edi
591 #else
592         mov     4(%edx), %ecx
593         cmp     4(%eax), %ecx
594 #endif
595         jne     L(more4bytes)
596         add     $0xfefefeff, %ecx
597         jnc     L(more4bytes)
598 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
599         xor     %edi, %ecx
600 #else
601         xor     4(%edx), %ecx
602 #endif
603         or      $0xfefefeff, %ecx
604         add     $1, %ecx
605         jnz     L(more4bytes)
606
607 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
608         sub     $8, REM
609         jbe     L(eq)
610 #endif
611
612         add     $8, %edx
613         add     $8, %eax
614 L(less4bytes):
615
616         movzbl  (%eax), %ecx
617 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
618         movzbl  (%edx), %edi
619 # ifdef PIC
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
622 # else
623         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
624         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
625 # endif
626         cmpl    %ecx, %edi
627 #else
628         cmpb    %cl, (%edx)
629 #endif
630         jne     L(neq)
631         cmpl    $0, %ecx
632         je      L(eq)
633
634 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
635         cmp     $1, REM
636         je      L(eq)
637 #endif
638         movzbl  1(%eax), %ecx
639 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
640         movzbl  1(%edx), %edi
641 # ifdef PIC
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
644 # else
645         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
646         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
647 # endif
648         cmpl    %ecx, %edi
649 #else
650         cmpb    %cl, 1(%edx)
651 #endif
652         jne     L(neq)
653         cmpl    $0, %ecx
654         je      L(eq)
655
656 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
657         cmp     $2, REM
658         je      L(eq)
659 #endif
660
661         movzbl  2(%eax), %ecx
662 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
663         movzbl  2(%edx), %edi
664 # ifdef PIC
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
667 # else
668         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
669         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
670 # endif
671         cmpl    %ecx, %edi
672 #else
673         cmpb    %cl, 2(%edx)
674 #endif
675         jne     L(neq)
676         cmpl    $0, %ecx
677         je      L(eq)
678
679 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
680         cmp     $3, REM
681         je      L(eq)
682 #endif
683         movzbl  3(%eax), %ecx
684 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
685         movzbl  3(%edx), %edi
686 # ifdef PIC
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
689 # else
690         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
691         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
692 # endif
693         cmpl    %ecx, %edi
694 #else
695         cmpb    %cl, 3(%edx)
696 #endif
697         jne     L(neq)
698         cmpl    $0, %ecx
699         je      L(eq)
700
701 L(more4bytes):
702 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
703         cmp     $4, REM
704         je      L(eq)
705 #endif
706         movzbl  4(%eax), %ecx
707 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
708         movzbl  4(%edx), %edi
709 # ifdef PIC
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
712 # else
713         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
714         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
715 # endif
716         cmpl    %ecx, %edi
717 #else
718         cmpb    %cl, 4(%edx)
719 #endif
720         jne     L(neq)
721         cmpl    $0, %ecx
722         je      L(eq)
723
724
725 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
726         cmp     $5, REM
727         je      L(eq)
728 #endif
729         movzbl  5(%eax), %ecx
730 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
731         movzbl  5(%edx), %edi
732 # ifdef PIC
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
735 # else
736         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
737         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
738 # endif
739         cmpl    %ecx, %edi
740 #else
741         cmpb    %cl, 5(%edx)
742 #endif
743         jne     L(neq)
744         cmpl    $0, %ecx
745         je      L(eq)
746
747 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
748         cmp     $6, REM
749         je      L(eq)
750 #endif
751         movzbl  6(%eax), %ecx
752 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
753         movzbl  6(%edx), %edi
754 # ifdef PIC
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
757 # else
758         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
759         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
760 # endif
761         cmpl    %ecx, %edi
762 #else
763         cmpb    %cl, 6(%edx)
764 #endif
765         jne     L(neq)
766         cmpl    $0, %ecx
767         je      L(eq)
768
769 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
770         cmp     $7, REM
771         je      L(eq)
772 #endif
773         movzbl  7(%eax), %ecx
774 #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
775         movzbl  7(%edx), %edi
776 # ifdef PIC
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
779 # else
780         movl    _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx
781         movl    _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi
782 # endif
783         cmpl    %ecx, %edi
784 #else
785         cmpb    %cl, 7(%edx)
786 #endif
787         jne     L(neq)
788         jmp     L(eq)
789
790 END (STRCMP)
791
792 #endif