Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / i386 / i686 / multiarch / memchr-sse2.S
blob8d2c159cea6a4168d57ee25d10e77a2ca71e3817
1 /* Optimized memchr with sse2 without bsf
2    Copyright (C) 2011-2014 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/>.  */
20 #ifndef  NOT_IN_libc
22 # include <sysdep.h>
24 # define CFI_PUSH(REG)  \
25         cfi_adjust_cfa_offset (4);      \
26         cfi_rel_offset (REG, 0)
28 # define CFI_POP(REG)   \
29         cfi_adjust_cfa_offset (-4);     \
30         cfi_restore (REG)
32 # define PUSH(REG) pushl REG; CFI_PUSH (REG)
33 # define POP(REG) popl REG; CFI_POP (REG)
35 # ifndef USE_AS_RAWMEMCHR
36 #  define ENTRANCE PUSH(%edi);
37 #  define PARMS  8
38 #  define RETURN  POP(%edi); ret; CFI_PUSH(%edi);
39 # else
40 #  define ENTRANCE
41 #  define PARMS  4
42 # endif
44 # define STR1  PARMS
45 # define STR2  STR1+4
47 # ifndef USE_AS_RAWMEMCHR
48 #  define LEN   STR2+4
49 # endif
51 # ifndef MEMCHR
52 #  define MEMCHR __memchr_sse2
53 # endif
55         atom_text_section
56 ENTRY (MEMCHR)
57         ENTRANCE
58         mov     STR1(%esp), %ecx
59         movd    STR2(%esp), %xmm1
60 # ifndef USE_AS_RAWMEMCHR
61         mov     LEN(%esp), %edx
62         test    %edx, %edx
63         jz      L(return_null)
64 # endif
66         punpcklbw %xmm1, %xmm1
67 # ifndef USE_AS_RAWMEMCHR
68         mov     %ecx, %edi
69 # else
70         mov     %ecx, %edx
71 # endif
72         punpcklbw %xmm1, %xmm1
74         and     $63, %ecx
75         pshufd  $0, %xmm1, %xmm1
76         cmp     $48, %ecx
77         ja      L(crosscache)
79 # ifndef USE_AS_RAWMEMCHR
80         movdqu  (%edi), %xmm0
81 # else
82         movdqu  (%edx), %xmm0
83 # endif
84         pcmpeqb %xmm1, %xmm0
85         pmovmskb %xmm0, %eax
86         test    %eax, %eax
87 # ifndef USE_AS_RAWMEMCHR
88         jnz     L(match_case2_prolog)
90         sub     $16, %edx
91         jbe     L(return_null)
92         lea     16(%edi), %edi
93         and     $15, %ecx
94         and     $-16, %edi
95         add     %ecx, %edx
96 # else
97         jnz     L(match_case1_prolog)
98         lea     16(%edx), %edx
99         and     $-16, %edx
100 # endif
101         jmp     L(loop_prolog)
103         .p2align 4
104 L(crosscache):
105         and     $15, %ecx
106 # ifndef USE_AS_RAWMEMCHR
107         and     $-16, %edi
108         movdqa  (%edi), %xmm0
109 # else
110         and     $-16, %edx
111         movdqa  (%edx), %xmm0
112 # endif
113         pcmpeqb %xmm1, %xmm0
114         pmovmskb %xmm0, %eax
115         sar     %cl, %eax
116         test    %eax, %eax
118 # ifndef USE_AS_RAWMEMCHR
119         jnz     L(match_case2_prolog1)
120         lea     -16(%edx), %edx
121         add     %ecx, %edx
122         jle     L(return_null)
123         lea     16(%edi), %edi
124 # else
125         jnz     L(match_case1_prolog1)
126         lea     16(%edx), %edx
127 # endif
129         .p2align 4
130 L(loop_prolog):
131 # ifndef USE_AS_RAWMEMCHR
132         sub     $64, %edx
133         jbe     L(exit_loop)
134         movdqa  (%edi), %xmm0
135 # else
136         movdqa  (%edx), %xmm0
137 # endif
138         pcmpeqb %xmm1, %xmm0
139         xor     %ecx, %ecx
140         pmovmskb %xmm0, %eax
141         test    %eax, %eax
142         jnz     L(match_case1)
144 # ifndef USE_AS_RAWMEMCHR
145         movdqa  16(%edi), %xmm2
146 # else
147         movdqa  16(%edx), %xmm2
148 # endif
149         pcmpeqb %xmm1, %xmm2
150         lea     16(%ecx), %ecx
151         pmovmskb %xmm2, %eax
152         test    %eax, %eax
153         jnz     L(match_case1)
155 # ifndef USE_AS_RAWMEMCHR
156         movdqa  32(%edi), %xmm3
157 # else
158         movdqa  32(%edx), %xmm3
159 # endif
160         pcmpeqb %xmm1, %xmm3
161         lea     16(%ecx), %ecx
162         pmovmskb %xmm3, %eax
163         test    %eax, %eax
164         jnz     L(match_case1)
166 # ifndef USE_AS_RAWMEMCHR
167         movdqa  48(%edi), %xmm4
168 # else
169         movdqa  48(%edx), %xmm4
170 # endif
171         pcmpeqb %xmm1, %xmm4
172         lea     16(%ecx), %ecx
173         pmovmskb %xmm4, %eax
174         test    %eax, %eax
175         jnz     L(match_case1)
177 # ifndef USE_AS_RAWMEMCHR
178         lea     64(%edi), %edi
179         sub     $64, %edx
180         jbe     L(exit_loop)
182         movdqa  (%edi), %xmm0
183 # else
184         lea     64(%edx), %edx
185         movdqa  (%edx), %xmm0
186 # endif
187         pcmpeqb %xmm1, %xmm0
188         xor     %ecx, %ecx
189         pmovmskb %xmm0, %eax
190         test    %eax, %eax
191         jnz     L(match_case1)
193 # ifndef USE_AS_RAWMEMCHR
194         movdqa  16(%edi), %xmm2
195 # else
196         movdqa  16(%edx), %xmm2
197 # endif
198         pcmpeqb %xmm1, %xmm2
199         lea     16(%ecx), %ecx
200         pmovmskb %xmm2, %eax
201         test    %eax, %eax
202         jnz     L(match_case1)
204 # ifndef USE_AS_RAWMEMCHR
205         movdqa  32(%edi), %xmm3
206 # else
207         movdqa  32(%edx), %xmm3
208 # endif
209         pcmpeqb %xmm1, %xmm3
210         lea     16(%ecx), %ecx
211         pmovmskb %xmm3, %eax
212         test    %eax, %eax
213         jnz     L(match_case1)
215 # ifndef USE_AS_RAWMEMCHR
216         movdqa  48(%edi), %xmm4
217 # else
218         movdqa  48(%edx), %xmm4
219 # endif
220         pcmpeqb %xmm1, %xmm4
221         lea     16(%ecx), %ecx
222         pmovmskb %xmm4, %eax
223         test    %eax, %eax
224         jnz     L(match_case1)
226 # ifndef USE_AS_RAWMEMCHR
227         lea     64(%edi), %edi
228         mov     %edi, %ecx
229         and     $-64, %edi
230         and     $63, %ecx
231         add     %ecx, %edx
232 # else
233         lea     64(%edx), %edx
234         and     $-64, %edx
235 # endif
237         .p2align 4
238 L(align64_loop):
240 # ifndef USE_AS_RAWMEMCHR
241         sub     $64, %edx
242         jbe     L(exit_loop)
243         movdqa  (%edi), %xmm0
244         movdqa  16(%edi), %xmm2
245         movdqa  32(%edi), %xmm3
246         movdqa  48(%edi), %xmm4
247 # else
248         movdqa  (%edx), %xmm0
249         movdqa  16(%edx), %xmm2
250         movdqa  32(%edx), %xmm3
251         movdqa  48(%edx), %xmm4
252 # endif
253         pcmpeqb %xmm1, %xmm0
254         pcmpeqb %xmm1, %xmm2
255         pcmpeqb %xmm1, %xmm3
256         pcmpeqb %xmm1, %xmm4
258         pmaxub  %xmm0, %xmm3
259         pmaxub  %xmm2, %xmm4
260         pmaxub  %xmm3, %xmm4
261 # ifndef USE_AS_RAWMEMCHR
262         add     $64, %edi
263 # else
264         add     $64, %edx
265 # endif
266         pmovmskb %xmm4, %eax
268         test    %eax, %eax
269         jz      L(align64_loop)
271 # ifndef USE_AS_RAWMEMCHR
272         sub     $64, %edi
273 # else
274         sub     $64, %edx
275 # endif
277         pmovmskb %xmm0, %eax
278         xor     %ecx, %ecx
279         test    %eax, %eax
280         jnz     L(match_case1)
282         pmovmskb %xmm2, %eax
283         lea     16(%ecx), %ecx
284         test    %eax, %eax
285         jnz     L(match_case1)
287 # ifndef USE_AS_RAWMEMCHR
288         movdqa  32(%edi), %xmm3
289 # else
290         movdqa  32(%edx), %xmm3
291 # endif
292         pcmpeqb %xmm1, %xmm3
293         pmovmskb %xmm3, %eax
294         lea     16(%ecx), %ecx
295         test    %eax, %eax
296         jnz     L(match_case1)
298 # ifndef USE_AS_RAWMEMCHR
299         pcmpeqb 48(%edi), %xmm1
300 # else
301         pcmpeqb 48(%edx), %xmm1
302 # endif
303         pmovmskb %xmm1, %eax
304         lea     16(%ecx), %ecx
306         .p2align 4
307 L(match_case1):
308 # ifndef USE_AS_RAWMEMCHR
309         add     %ecx, %edi
310 # else
311 L(match_case1_prolog1):
312         add     %ecx, %edx
313 L(match_case1_prolog):
314 # endif
315         test    %al, %al
316         jz      L(match_case1_high)
317         mov     %al, %cl
318         and     $15, %cl
319         jz      L(match_case1_8)
320         test    $0x01, %al
321         jnz     L(ExitCase1_1)
322         test    $0x02, %al
323         jnz     L(ExitCase1_2)
324         test    $0x04, %al
325         jnz     L(ExitCase1_3)
326 # ifndef USE_AS_RAWMEMCHR
327         lea     3(%edi), %eax
328         RETURN
329 # else
330         lea     3(%edx), %eax
331         ret
332 # endif
334         .p2align 4
335 L(match_case1_8):
336         test    $0x10, %al
337         jnz     L(ExitCase1_5)
338         test    $0x20, %al
339         jnz     L(ExitCase1_6)
340         test    $0x40, %al
341         jnz     L(ExitCase1_7)
342 # ifndef USE_AS_RAWMEMCHR
343         lea     7(%edi), %eax
344         RETURN
345 # else
346         lea     7(%edx), %eax
347         ret
348 # endif
350         .p2align 4
351 L(match_case1_high):
352         mov     %ah, %ch
353         and     $15, %ch
354         jz      L(match_case1_high_8)
355         test    $0x01, %ah
356         jnz     L(ExitCase1_9)
357         test    $0x02, %ah
358         jnz     L(ExitCase1_10)
359         test    $0x04, %ah
360         jnz     L(ExitCase1_11)
361 # ifndef USE_AS_RAWMEMCHR
362         lea     11(%edi), %eax
363         RETURN
364 # else
365         lea     11(%edx), %eax
366         ret
367 # endif
369         .p2align 4
370 L(match_case1_high_8):
371         test    $0x10, %ah
372         jnz     L(ExitCase1_13)
373         test    $0x20, %ah
374         jnz     L(ExitCase1_14)
375         test    $0x40, %ah
376         jnz     L(ExitCase1_15)
377 # ifndef USE_AS_RAWMEMCHR
378         lea     15(%edi), %eax
379         RETURN
380 # else
381         lea     15(%edx), %eax
382         ret
383 # endif
385 # ifndef USE_AS_RAWMEMCHR
386         .p2align 4
387 L(exit_loop):
388         add     $64, %edx
390         movdqa  (%edi), %xmm0
391         pcmpeqb %xmm1, %xmm0
392         xor     %ecx, %ecx
393         pmovmskb %xmm0, %eax
394         test    %eax, %eax
395         jnz     L(match_case2)
396         cmp     $16, %edx
397         jbe     L(return_null)
399         movdqa  16(%edi), %xmm2
400         pcmpeqb %xmm1, %xmm2
401         lea     16(%ecx), %ecx
402         pmovmskb %xmm2, %eax
403         test    %eax, %eax
404         jnz     L(match_case2)
405         cmp     $32, %edx
406         jbe     L(return_null)
408         movdqa  32(%edi), %xmm3
409         pcmpeqb %xmm1, %xmm3
410         lea     16(%ecx), %ecx
411         pmovmskb %xmm3, %eax
412         test    %eax, %eax
413         jnz     L(match_case2)
414         cmp     $48, %edx
415         jbe     L(return_null)
417         pcmpeqb 48(%edi), %xmm1
418         lea     16(%ecx), %ecx
419         pmovmskb %xmm1, %eax
420         test    %eax, %eax
421         jnz     L(match_case2)
423         xor     %eax, %eax
424         RETURN
425 # endif
427         .p2align 4
428 L(ExitCase1_1):
429 # ifndef USE_AS_RAWMEMCHR
430         mov     %edi, %eax
431         RETURN
432 # else
433         mov     %edx, %eax
434         ret
435 # endif
437         .p2align 4
438 L(ExitCase1_2):
439 # ifndef USE_AS_RAWMEMCHR
440         lea     1(%edi), %eax
441         RETURN
442 # else
443         lea     1(%edx), %eax
444         ret
445 # endif
447         .p2align 4
448 L(ExitCase1_3):
449 # ifndef USE_AS_RAWMEMCHR
450         lea     2(%edi), %eax
451         RETURN
452 # else
453         lea     2(%edx), %eax
454         ret
455 # endif
457         .p2align 4
458 L(ExitCase1_5):
459 # ifndef USE_AS_RAWMEMCHR
460         lea     4(%edi), %eax
461         RETURN
462 # else
463         lea     4(%edx), %eax
464         ret
465 # endif
467         .p2align 4
468 L(ExitCase1_6):
469 # ifndef USE_AS_RAWMEMCHR
470         lea     5(%edi), %eax
471         RETURN
472 # else
473         lea     5(%edx), %eax
474         ret
475 # endif
477         .p2align 4
478 L(ExitCase1_7):
479 # ifndef USE_AS_RAWMEMCHR
480         lea     6(%edi), %eax
481         RETURN
482 # else
483         lea     6(%edx), %eax
484         ret
485 # endif
487         .p2align 4
488 L(ExitCase1_9):
489 # ifndef USE_AS_RAWMEMCHR
490         lea     8(%edi), %eax
491         RETURN
492 # else
493         lea     8(%edx), %eax
494         ret
495 # endif
497         .p2align 4
498 L(ExitCase1_10):
499 # ifndef USE_AS_RAWMEMCHR
500         lea     9(%edi), %eax
501         RETURN
502 # else
503         lea     9(%edx), %eax
504         ret
505 # endif
507         .p2align 4
508 L(ExitCase1_11):
509 # ifndef USE_AS_RAWMEMCHR
510         lea     10(%edi), %eax
511         RETURN
512 # else
513         lea     10(%edx), %eax
514         ret
515 # endif
517         .p2align 4
518 L(ExitCase1_13):
519 # ifndef USE_AS_RAWMEMCHR
520         lea     12(%edi), %eax
521         RETURN
522 # else
523         lea     12(%edx), %eax
524         ret
525 # endif
527         .p2align 4
528 L(ExitCase1_14):
529 # ifndef USE_AS_RAWMEMCHR
530         lea     13(%edi), %eax
531         RETURN
532 # else
533         lea     13(%edx), %eax
534         ret
535 # endif
537         .p2align 4
538 L(ExitCase1_15):
539 # ifndef USE_AS_RAWMEMCHR
540         lea     14(%edi), %eax
541         RETURN
542 # else
543         lea     14(%edx), %eax
544         ret
545 # endif
547 # ifndef USE_AS_RAWMEMCHR
548         .p2align 4
549 L(match_case2):
550         sub     %ecx, %edx
551 L(match_case2_prolog1):
552         add     %ecx, %edi
553 L(match_case2_prolog):
554         test    %al, %al
555         jz      L(match_case2_high)
556         mov     %al, %cl
557         and     $15, %cl
558         jz      L(match_case2_8)
559         test    $0x01, %al
560         jnz     L(ExitCase2_1)
561         test    $0x02, %al
562         jnz     L(ExitCase2_2)
563         test    $0x04, %al
564         jnz     L(ExitCase2_3)
565         sub     $4, %edx
566         jb      L(return_null)
567         lea     3(%edi), %eax
568         RETURN
570         .p2align 4
571 L(match_case2_8):
572         test    $0x10, %al
573         jnz     L(ExitCase2_5)
574         test    $0x20, %al
575         jnz     L(ExitCase2_6)
576         test    $0x40, %al
577         jnz     L(ExitCase2_7)
578         sub     $8, %edx
579         jb      L(return_null)
580         lea     7(%edi), %eax
581         RETURN
583         .p2align 4
584 L(match_case2_high):
585         mov     %ah, %ch
586         and     $15, %ch
587         jz      L(match_case2_high_8)
588         test    $0x01, %ah
589         jnz     L(ExitCase2_9)
590         test    $0x02, %ah
591         jnz     L(ExitCase2_10)
592         test    $0x04, %ah
593         jnz     L(ExitCase2_11)
594         sub     $12, %edx
595         jb      L(return_null)
596         lea     11(%edi), %eax
597         RETURN
599         .p2align 4
600 L(match_case2_high_8):
601         test    $0x10, %ah
602         jnz     L(ExitCase2_13)
603         test    $0x20, %ah
604         jnz     L(ExitCase2_14)
605         test    $0x40, %ah
606         jnz     L(ExitCase2_15)
607         sub     $16, %edx
608         jb      L(return_null)
609         lea     15(%edi), %eax
610         RETURN
612         .p2align 4
613 L(ExitCase2_1):
614         mov     %edi, %eax
615         RETURN
617         .p2align 4
618 L(ExitCase2_2):
619         sub     $2, %edx
620         jb      L(return_null)
621         lea     1(%edi), %eax
622         RETURN
624         .p2align 4
625 L(ExitCase2_3):
626         sub     $3, %edx
627         jb      L(return_null)
628         lea     2(%edi), %eax
629         RETURN
631         .p2align 4
632 L(ExitCase2_5):
633         sub     $5, %edx
634         jb      L(return_null)
635         lea     4(%edi), %eax
636         RETURN
638         .p2align 4
639 L(ExitCase2_6):
640         sub     $6, %edx
641         jb      L(return_null)
642         lea     5(%edi), %eax
643         RETURN
645         .p2align 4
646 L(ExitCase2_7):
647         sub     $7, %edx
648         jb      L(return_null)
649         lea     6(%edi), %eax
650         RETURN
652         .p2align 4
653 L(ExitCase2_9):
654         sub     $9, %edx
655         jb      L(return_null)
656         lea     8(%edi), %eax
657         RETURN
659         .p2align 4
660 L(ExitCase2_10):
661         sub     $10, %edx
662         jb      L(return_null)
663         lea     9(%edi), %eax
664         RETURN
666         .p2align 4
667 L(ExitCase2_11):
668         sub     $11, %edx
669         jb      L(return_null)
670         lea     10(%edi), %eax
671         RETURN
673         .p2align 4
674 L(ExitCase2_13):
675         sub     $13, %edx
676         jb      L(return_null)
677         lea     12(%edi), %eax
678         RETURN
680         .p2align 4
681 L(ExitCase2_14):
682         sub     $14, %edx
683         jb      L(return_null)
684         lea     13(%edi), %eax
685         RETURN
687         .p2align 4
688 L(ExitCase2_15):
689         sub     $15, %edx
690         jb      L(return_null)
691         lea     14(%edi), %eax
692         RETURN
693 # endif
695         .p2align 4
696 L(return_null):
697         xor     %eax, %eax
698 # ifndef USE_AS_RAWMEMCHR
699         RETURN
700 # else
701         ret
702 # endif
704 END (MEMCHR)
705 #endif