Replace FSF snail mail address with URLs.
[glibc.git] / sysdeps / x86_64 / multiarch / strrchr-sse2-no-bsf.S
blobc698c947eb097ccbc3c3ece0e4b0fd8361992cd7
1 /* strrchr with SSE2 without bsf and bsr
2    Copyright (C) 2011 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 #if defined SHARED && !defined NOT_IN_libc
22 # include <sysdep.h>
23 # include "asm-syntax.h"
25         atom_text_section
26 ENTRY (__strrchr_sse2_no_bsf)
28         movd    %rsi, %xmm1
29         pxor    %xmm2, %xmm2
30         mov     %rdi, %rcx
31         punpcklbw %xmm1, %xmm1
32         punpcklbw %xmm1, %xmm1
33         /* ECX has OFFSET. */
34         and     $63, %rcx
35         cmp     $48, %rcx
36         pshufd  $0, %xmm1, %xmm1
37         ja      L(crosscache)
39 /* unaligned string. */
40         movdqu  (%rdi), %xmm0
41         pcmpeqb %xmm0, %xmm2
42         pcmpeqb %xmm1, %xmm0
43         /* Find where NULL is.  */
44         pmovmskb %xmm2, %rcx
45         /* Check if there is a match.  */
46         pmovmskb %xmm0, %rax
47         add     $16, %rdi
49         test    %rax, %rax
50         jnz     L(unaligned_match1)
52         test    %rcx, %rcx
53         jnz     L(return_null)
55         and     $-16, %rdi
56         xor     %r8, %r8
57         jmp     L(loop)
59         .p2align 4
60 L(unaligned_match1):
61         test    %rcx, %rcx
62         jnz     L(prolog_find_zero_1)
64         mov     %rax, %r8
65         mov     %rdi, %rsi
66         and     $-16, %rdi
67         jmp     L(loop)
69         .p2align 4
70 L(crosscache):
71 /* Hancle unaligned string.  */
72         and     $15, %rcx
73         and     $-16, %rdi
74         pxor    %xmm3, %xmm3
75         movdqa  (%rdi), %xmm0
76         pcmpeqb %xmm0, %xmm3
77         pcmpeqb %xmm1, %xmm0
78         /* Find where NULL is.  */
79         pmovmskb %xmm3, %rdx
80         /* Check if there is a match.  */
81         pmovmskb %xmm0, %rax
82         /* Remove the leading bytes.  */
83         shr     %cl, %rdx
84         shr     %cl, %rax
85         add     $16, %rdi
87         test    %rax, %rax
88         jnz     L(unaligned_match)
90         test    %rdx, %rdx
91         jnz     L(return_null)
93         xor     %r8, %r8
94         jmp     L(loop)
96         .p2align 4
97 L(unaligned_match):
98         test    %rdx, %rdx
99         jnz     L(prolog_find_zero)
101         mov     %rax, %r8
102         lea     (%rdi, %rcx), %rsi
104 /* Loop start on aligned string.  */
105         .p2align 4
106 L(loop):
107         movdqa  (%rdi), %xmm0
108         pcmpeqb %xmm0, %xmm2
109         add     $16, %rdi
110         pcmpeqb %xmm1, %xmm0
111         pmovmskb %xmm2, %rcx
112         pmovmskb %xmm0, %rax
113         or      %rax, %rcx
114         jnz     L(matches)
116         movdqa  (%rdi), %xmm0
117         pcmpeqb %xmm0, %xmm2
118         add     $16, %rdi
119         pcmpeqb %xmm1, %xmm0
120         pmovmskb %xmm2, %rcx
121         pmovmskb %xmm0, %rax
122         or      %rax, %rcx
123         jnz     L(matches)
125         movdqa  (%rdi), %xmm0
126         pcmpeqb %xmm0, %xmm2
127         add     $16, %rdi
128         pcmpeqb %xmm1, %xmm0
129         pmovmskb %xmm2, %rcx
130         pmovmskb %xmm0, %rax
131         or      %rax, %rcx
132         jnz     L(matches)
134         movdqa  (%rdi), %xmm0
135         pcmpeqb %xmm0, %xmm2
136         add     $16, %rdi
137         pcmpeqb %xmm1, %xmm0
138         pmovmskb %xmm2, %rcx
139         pmovmskb %xmm0, %rax
140         or      %rax, %rcx
141         jz      L(loop)
143 L(matches):
144         test    %rax, %rax
145         jnz     L(match)
146 L(return_value):
147         test    %r8, %r8
148         jz      L(return_null)
149         mov     %r8, %rax
150         mov     %rsi, %rdi
151         jmp     L(match_exit)
153         .p2align 4
154 L(match):
155         pmovmskb %xmm2, %rcx
156         test    %rcx, %rcx
157         jnz     L(find_zero)
158         mov     %rax, %r8
159         mov     %rdi, %rsi
160         jmp     L(loop)
162         .p2align 4
163 L(find_zero):
164         test    %cl, %cl
165         jz      L(find_zero_high)
166         mov     %cl, %dl
167         and     $15, %dl
168         jz      L(find_zero_8)
169         test    $0x01, %cl
170         jnz     L(FindZeroExit1)
171         test    $0x02, %cl
172         jnz     L(FindZeroExit2)
173         test    $0x04, %cl
174         jnz     L(FindZeroExit3)
175         and     $1 << 4 - 1, %rax
176         jz      L(return_value)
177         jmp     L(match_exit)
179         .p2align 4
180 L(find_zero_8):
181         test    $0x10, %cl
182         jnz     L(FindZeroExit5)
183         test    $0x20, %cl
184         jnz     L(FindZeroExit6)
185         test    $0x40, %cl
186         jnz     L(FindZeroExit7)
187         and     $1 << 8 - 1, %rax
188         jz      L(return_value)
189         jmp     L(match_exit)
191         .p2align 4
192 L(find_zero_high):
193         mov     %ch, %dh
194         and     $15, %dh
195         jz      L(find_zero_high_8)
196         test    $0x01, %ch
197         jnz     L(FindZeroExit9)
198         test    $0x02, %ch
199         jnz     L(FindZeroExit10)
200         test    $0x04, %ch
201         jnz     L(FindZeroExit11)
202         and     $1 << 12 - 1, %rax
203         jz      L(return_value)
204         jmp     L(match_exit)
206         .p2align 4
207 L(find_zero_high_8):
208         test    $0x10, %ch
209         jnz     L(FindZeroExit13)
210         test    $0x20, %ch
211         jnz     L(FindZeroExit14)
212         test    $0x40, %ch
213         jnz     L(FindZeroExit15)
214         and     $1 << 16 - 1, %rax
215         jz      L(return_value)
216         jmp     L(match_exit)
218         .p2align 4
219 L(FindZeroExit1):
220         and     $1, %rax
221         jz      L(return_value)
222         jmp     L(match_exit)
224         .p2align 4
225 L(FindZeroExit2):
226         and     $1 << 2 - 1, %rax
227         jz      L(return_value)
228         jmp     L(match_exit)
230         .p2align 4
231 L(FindZeroExit3):
232         and     $1 << 3 - 1, %rax
233         jz      L(return_value)
234         jmp     L(match_exit)
236         .p2align 4
237 L(FindZeroExit5):
238         and     $1 << 5 - 1, %rax
239         jz      L(return_value)
240         jmp     L(match_exit)
242         .p2align 4
243 L(FindZeroExit6):
244         and     $1 << 6 - 1, %rax
245         jz      L(return_value)
246         jmp     L(match_exit)
248         .p2align 4
249 L(FindZeroExit7):
250         and     $1 << 7 - 1, %rax
251         jz      L(return_value)
252         jmp     L(match_exit)
254         .p2align 4
255 L(FindZeroExit9):
256         and     $1 << 9 - 1, %rax
257         jz      L(return_value)
258         jmp     L(match_exit)
260         .p2align 4
261 L(FindZeroExit10):
262         and     $1 << 10 - 1, %rax
263         jz      L(return_value)
264         jmp     L(match_exit)
266         .p2align 4
267 L(FindZeroExit11):
268         and     $1 << 11 - 1, %rax
269         jz      L(return_value)
270         jmp     L(match_exit)
272         .p2align 4
273 L(FindZeroExit13):
274         and     $1 << 13 - 1, %rax
275         jz      L(return_value)
276         jmp     L(match_exit)
278         .p2align 4
279 L(FindZeroExit14):
280         and     $1 << 14 - 1, %rax
281         jz      L(return_value)
282         jmp     L(match_exit)
284         .p2align 4
285 L(FindZeroExit15):
286         and     $1 << 15 - 1, %rax
287         jz      L(return_value)
289         .p2align 4
290 L(match_exit):
291         test    %ah, %ah
292         jnz     L(match_exit_high)
293         mov     %al, %dl
294         and     $15 << 4, %dl
295         jnz     L(match_exit_8)
296         test    $0x08, %al
297         jnz     L(Exit4)
298         test    $0x04, %al
299         jnz     L(Exit3)
300         test    $0x02, %al
301         jnz     L(Exit2)
302         lea     -16(%rdi), %rax
303         ret
305         .p2align 4
306 L(match_exit_8):
307         test    $0x80, %al
308         jnz     L(Exit8)
309         test    $0x40, %al
310         jnz     L(Exit7)
311         test    $0x20, %al
312         jnz     L(Exit6)
313         lea     -12(%rdi), %rax
314         ret
316         .p2align 4
317 L(match_exit_high):
318         mov     %ah, %dh
319         and     $15 << 4, %dh
320         jnz     L(match_exit_high_8)
321         test    $0x08, %ah
322         jnz     L(Exit12)
323         test    $0x04, %ah
324         jnz     L(Exit11)
325         test    $0x02, %ah
326         jnz     L(Exit10)
327         lea     -8(%rdi), %rax
328         ret
330         .p2align 4
331 L(match_exit_high_8):
332         test    $0x80, %ah
333         jnz     L(Exit16)
334         test    $0x40, %ah
335         jnz     L(Exit15)
336         test    $0x20, %ah
337         jnz     L(Exit14)
338         lea     -4(%rdi), %rax
339         ret
341         .p2align 4
342 L(Exit2):
343         lea     -15(%rdi), %rax
344         ret
346         .p2align 4
347 L(Exit3):
348         lea     -14(%rdi), %rax
349         ret
351         .p2align 4
352 L(Exit4):
353         lea     -13(%rdi), %rax
354         ret
356         .p2align 4
357 L(Exit6):
358         lea     -11(%rdi), %rax
359         ret
361         .p2align 4
362 L(Exit7):
363         lea     -10(%rdi), %rax
364         ret
366         .p2align 4
367 L(Exit8):
368         lea     -9(%rdi), %rax
369         ret
371         .p2align 4
372 L(Exit10):
373         lea     -7(%rdi), %rax
374         ret
376         .p2align 4
377 L(Exit11):
378         lea     -6(%rdi), %rax
379         ret
381         .p2align 4
382 L(Exit12):
383         lea     -5(%rdi), %rax
384         ret
386         .p2align 4
387 L(Exit14):
388         lea     -3(%rdi), %rax
389         ret
391         .p2align 4
392 L(Exit15):
393         lea     -2(%rdi), %rax
394         ret
396         .p2align 4
397 L(Exit16):
398         lea     -1(%rdi), %rax
399         ret
401 /* Return NULL.  */
402         .p2align 4
403 L(return_null):
404         xor     %rax, %rax
405         ret
407         .p2align 4
408 L(prolog_find_zero):
409         add     %rcx, %rdi
410         mov     %rdx, %rcx
411 L(prolog_find_zero_1):
412         test    %cl, %cl
413         jz      L(prolog_find_zero_high)
414         mov     %cl, %dl
415         and     $15, %dl
416         jz      L(prolog_find_zero_8)
417         test    $0x01, %cl
418         jnz     L(PrologFindZeroExit1)
419         test    $0x02, %cl
420         jnz     L(PrologFindZeroExit2)
421         test    $0x04, %cl
422         jnz     L(PrologFindZeroExit3)
423         and     $1 << 4 - 1, %rax
424         jnz     L(match_exit)
425         xor     %rax, %rax
426         ret
428         .p2align 4
429 L(prolog_find_zero_8):
430         test    $0x10, %cl
431         jnz     L(PrologFindZeroExit5)
432         test    $0x20, %cl
433         jnz     L(PrologFindZeroExit6)
434         test    $0x40, %cl
435         jnz     L(PrologFindZeroExit7)
436         and     $1 << 8 - 1, %rax
437         jnz     L(match_exit)
438         xor     %rax, %rax
439         ret
441         .p2align 4
442 L(prolog_find_zero_high):
443         mov     %ch, %dh
444         and     $15, %dh
445         jz      L(prolog_find_zero_high_8)
446         test    $0x01, %ch
447         jnz     L(PrologFindZeroExit9)
448         test    $0x02, %ch
449         jnz     L(PrologFindZeroExit10)
450         test    $0x04, %ch
451         jnz     L(PrologFindZeroExit11)
452         and     $1 << 12 - 1, %rax
453         jnz     L(match_exit)
454         xor     %rax, %rax
455         ret
457         .p2align 4
458 L(prolog_find_zero_high_8):
459         test    $0x10, %ch
460         jnz     L(PrologFindZeroExit13)
461         test    $0x20, %ch
462         jnz     L(PrologFindZeroExit14)
463         test    $0x40, %ch
464         jnz     L(PrologFindZeroExit15)
465         and     $1 << 16 - 1, %rax
466         jnz     L(match_exit)
467         xor     %rax, %rax
468         ret
470         .p2align 4
471 L(PrologFindZeroExit1):
472         and     $1, %rax
473         jnz     L(match_exit)
474         xor     %rax, %rax
475         ret
477         .p2align 4
478 L(PrologFindZeroExit2):
479         and     $1 << 2 - 1, %rax
480         jnz     L(match_exit)
481         xor     %rax, %rax
482         ret
484         .p2align 4
485 L(PrologFindZeroExit3):
486         and     $1 << 3 - 1, %rax
487         jnz     L(match_exit)
488         xor     %rax, %rax
489         ret
491         .p2align 4
492 L(PrologFindZeroExit5):
493         and     $1 << 5 - 1, %rax
494         jnz     L(match_exit)
495         xor     %rax, %rax
496         ret
498         .p2align 4
499 L(PrologFindZeroExit6):
500         and     $1 << 6 - 1, %rax
501         jnz     L(match_exit)
502         xor     %rax, %rax
503         ret
505         .p2align 4
506 L(PrologFindZeroExit7):
507         and     $1 << 7 - 1, %rax
508         jnz     L(match_exit)
509         xor     %rax, %rax
510         ret
512         .p2align 4
513 L(PrologFindZeroExit9):
514         and     $1 << 9 - 1, %rax
515         jnz     L(match_exit)
516         xor     %rax, %rax
517         ret
519         .p2align 4
520 L(PrologFindZeroExit10):
521         and     $1 << 10 - 1, %rax
522         jnz     L(match_exit)
523         xor     %rax, %rax
524         ret
526         .p2align 4
527 L(PrologFindZeroExit11):
528         and     $1 << 11 - 1, %rax
529         jnz     L(match_exit)
530         xor     %rax, %rax
531         ret
533         .p2align 4
534 L(PrologFindZeroExit13):
535         and     $1 << 13 - 1, %rax
536         jnz     L(match_exit)
537         xor     %rax, %rax
538         ret
540         .p2align 4
541 L(PrologFindZeroExit14):
542         and     $1 << 14 - 1, %rax
543         jnz     L(match_exit)
544         xor     %rax, %rax
545         ret
547         .p2align 4
548 L(PrologFindZeroExit15):
549         and     $1 << 15 - 1, %rax
550         jnz     L(match_exit)
551         xor     %rax, %rax
552         ret
554 END (__strrchr_sse2_no_bsf)
555 #endif