Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / x86_64 / memrchr.S
blobff875f44ab9e39e383d88b20ec2380eb630b2737
1 /* fast SSE2 memrchr with 64 byte loop and pmaxub instruction using
3    Copyright (C) 2011-2014 Free Software Foundation, Inc.
4    Contributed by Intel Corporation.
5    This file is part of the GNU C Library.
7    The GNU C Library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2.1 of the License, or (at your option) any later version.
12    The GNU C Library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
17    You should have received a copy of the GNU Lesser General Public
18    License along with the GNU C Library; if not, see
19    <http://www.gnu.org/licenses/>.  */
21 #include <sysdep.h>
23         .text
24 ENTRY (memrchr)
25         movd    %rsi, %xmm1
27         sub     $16, %rdx
28         jbe     L(length_less16)
30         punpcklbw       %xmm1, %xmm1
31         punpcklbw       %xmm1, %xmm1
33         add     %rdx, %rdi
34         pshufd  $0, %xmm1, %xmm1
36         movdqu  (%rdi), %xmm0
37         pcmpeqb %xmm1, %xmm0
39 /* Check if there is a match.  */
40         pmovmskb        %xmm0, %eax
41         test    %eax, %eax
42         jnz     L(matches0)
44         sub     $64, %rdi
45         mov     %rdi, %rcx
46         and     $15, %rcx
47         jz      L(loop_prolog)
49         add     $16, %rdi
50         add     $16, %rdx
51         and     $-16, %rdi
52         sub     %rcx, %rdx
54         .p2align 4
55 L(loop_prolog):
56         sub     $64, %rdx
57         jbe     L(exit_loop)
59         movdqa  48(%rdi), %xmm0
60         pcmpeqb %xmm1, %xmm0
61         pmovmskb        %xmm0, %eax
62         test    %eax, %eax
63         jnz     L(matches48)
65         movdqa  32(%rdi), %xmm2
66         pcmpeqb %xmm1, %xmm2
67         pmovmskb        %xmm2, %eax
68         test    %eax, %eax
69         jnz     L(matches32)
71         movdqa  16(%rdi), %xmm3
72         pcmpeqb %xmm1, %xmm3
73         pmovmskb        %xmm3, %eax
74         test    %eax, %eax
75         jnz     L(matches16)
77         movdqa  (%rdi), %xmm4
78         pcmpeqb %xmm1, %xmm4
79         pmovmskb        %xmm4, %eax
80         test    %eax, %eax
81         jnz     L(matches0)
83         sub     $64, %rdi
84         sub     $64, %rdx
85         jbe     L(exit_loop)
87         movdqa  48(%rdi), %xmm0
88         pcmpeqb %xmm1, %xmm0
89         pmovmskb        %xmm0, %eax
90         test    %eax, %eax
91         jnz     L(matches48)
93         movdqa  32(%rdi), %xmm2
94         pcmpeqb %xmm1, %xmm2
95         pmovmskb        %xmm2, %eax
96         test    %eax, %eax
97         jnz     L(matches32)
99         movdqa  16(%rdi), %xmm3
100         pcmpeqb %xmm1, %xmm3
101         pmovmskb        %xmm3, %eax
102         test    %eax, %eax
103         jnz     L(matches16)
105         movdqa  (%rdi), %xmm3
106         pcmpeqb %xmm1, %xmm3
107         pmovmskb        %xmm3, %eax
108         test    %eax, %eax
109         jnz     L(matches0)
111         mov     %rdi, %rcx
112         and     $63, %rcx
113         jz      L(align64_loop)
115         add     $64, %rdi
116         add     $64, %rdx
117         and     $-64, %rdi
118         sub     %rcx, %rdx
120         .p2align 4
121 L(align64_loop):
122         sub     $64, %rdi
123         sub     $64, %rdx
124         jbe     L(exit_loop)
126         movdqa  (%rdi), %xmm0
127         movdqa  16(%rdi), %xmm2
128         movdqa  32(%rdi), %xmm3
129         movdqa  48(%rdi), %xmm4
131         pcmpeqb %xmm1, %xmm0
132         pcmpeqb %xmm1, %xmm2
133         pcmpeqb %xmm1, %xmm3
134         pcmpeqb %xmm1, %xmm4
136         pmaxub  %xmm3, %xmm0
137         pmaxub  %xmm4, %xmm2
138         pmaxub  %xmm0, %xmm2
139         pmovmskb        %xmm2, %eax
141         test    %eax, %eax
142         jz      L(align64_loop)
144         pmovmskb        %xmm4, %eax
145         test    %eax, %eax
146         jnz     L(matches48)
148         pmovmskb        %xmm3, %eax
149         test    %eax, %eax
150         jnz     L(matches32)
152         movdqa  16(%rdi), %xmm2
154         pcmpeqb %xmm1, %xmm2
155         pcmpeqb (%rdi), %xmm1
157         pmovmskb        %xmm2, %eax
158         test    %eax, %eax
159         jnz     L(matches16)
161         pmovmskb        %xmm1, %eax
162         bsr     %eax, %eax
164         add     %rdi, %rax
165         ret
167         .p2align 4
168 L(exit_loop):
169         add     $64, %rdx
170         cmp     $32, %rdx
171         jbe     L(exit_loop_32)
173         movdqa  48(%rdi), %xmm0
174         pcmpeqb %xmm1, %xmm0
175         pmovmskb        %xmm0, %eax
176         test    %eax, %eax
177         jnz     L(matches48)
179         movdqa  32(%rdi), %xmm2
180         pcmpeqb %xmm1, %xmm2
181         pmovmskb        %xmm2, %eax
182         test    %eax, %eax
183         jnz     L(matches32)
185         movdqa  16(%rdi), %xmm3
186         pcmpeqb %xmm1, %xmm3
187         pmovmskb        %xmm3, %eax
188         test    %eax, %eax
189         jnz     L(matches16_1)
190         cmp     $48, %rdx
191         jbe     L(return_null)
193         pcmpeqb (%rdi), %xmm1
194         pmovmskb        %xmm1, %eax
195         test    %eax, %eax
196         jnz     L(matches0_1)
197         xor     %eax, %eax
198         ret
200         .p2align 4
201 L(exit_loop_32):
202         movdqa  48(%rdi), %xmm0
203         pcmpeqb %xmm1, %xmm0
204         pmovmskb        %xmm0, %eax
205         test    %eax, %eax
206         jnz     L(matches48_1)
207         cmp     $16, %rdx
208         jbe     L(return_null)
210         pcmpeqb 32(%rdi), %xmm1
211         pmovmskb        %xmm1, %eax
212         test    %eax, %eax
213         jnz     L(matches32_1)
214         xor     %eax, %eax
215         ret
217         .p2align 4
218 L(matches0):
219         bsr     %eax, %eax
220         add     %rdi, %rax
221         ret
223         .p2align 4
224 L(matches16):
225         bsr     %eax, %eax
226         lea     16(%rax, %rdi), %rax
227         ret
229         .p2align 4
230 L(matches32):
231         bsr     %eax, %eax
232         lea     32(%rax, %rdi), %rax
233         ret
235         .p2align 4
236 L(matches48):
237         bsr     %eax, %eax
238         lea     48(%rax, %rdi), %rax
239         ret
241         .p2align 4
242 L(matches0_1):
243         bsr     %eax, %eax
244         sub     $64, %rdx
245         add     %rax, %rdx
246         jl      L(return_null)
247         add     %rdi, %rax
248         ret
250         .p2align 4
251 L(matches16_1):
252         bsr     %eax, %eax
253         sub     $48, %rdx
254         add     %rax, %rdx
255         jl      L(return_null)
256         lea     16(%rdi, %rax), %rax
257         ret
259         .p2align 4
260 L(matches32_1):
261         bsr     %eax, %eax
262         sub     $32, %rdx
263         add     %rax, %rdx
264         jl      L(return_null)
265         lea     32(%rdi, %rax), %rax
266         ret
268         .p2align 4
269 L(matches48_1):
270         bsr     %eax, %eax
271         sub     $16, %rdx
272         add     %rax, %rdx
273         jl      L(return_null)
274         lea     48(%rdi, %rax), %rax
275         ret
277         .p2align 4
278 L(return_null):
279         xor     %rax, %rax
280         ret
282         .p2align 4
283 L(length_less16_offset0):
284         test    %edx, %edx
285         jz      L(return_null)
287         mov     %dl, %cl
288         pcmpeqb (%rdi), %xmm1
290         mov     $1, %edx
291         sal     %cl, %edx
292         sub     $1, %edx
294         pmovmskb        %xmm1, %eax
296         and     %edx, %eax
297         test    %eax, %eax
298         jz      L(return_null)
300         bsr     %eax, %eax
301         add     %rdi, %rax
302         ret
304         .p2align 4
305 L(length_less16):
306         punpcklbw       %xmm1, %xmm1
307         punpcklbw       %xmm1, %xmm1
309         add     $16, %rdx
311         pshufd  $0, %xmm1, %xmm1
313         mov     %rdi, %rcx
314         and     $15, %rcx
315         jz      L(length_less16_offset0)
317         mov     %rdi, %rcx
318         and     $15, %rcx
319         mov     %cl, %dh
320         mov     %rcx, %r8
321         add     %dl, %dh
322         and     $-16, %rdi
324         sub     $16, %dh
325         ja      L(length_less16_part2)
327         pcmpeqb (%rdi), %xmm1
328         pmovmskb        %xmm1, %eax
330         sar     %cl, %eax
331         mov     %dl, %cl
333         mov     $1, %edx
334         sal     %cl, %edx
335         sub     $1, %edx
337         and     %edx, %eax
338         test    %eax, %eax
339         jz      L(return_null)
341         bsr     %eax, %eax
342         add     %rdi, %rax
343         add     %r8, %rax
344         ret
346         .p2align 4
347 L(length_less16_part2):
348         movdqa  16(%rdi), %xmm2
349         pcmpeqb %xmm1, %xmm2
350         pmovmskb        %xmm2, %eax
352         mov     %dh, %cl
353         mov     $1, %edx
354         sal     %cl, %edx
355         sub     $1, %edx
357         and     %edx, %eax
359         test    %eax, %eax
360         jnz     L(length_less16_part2_return)
362         pcmpeqb (%rdi), %xmm1
363         pmovmskb        %xmm1, %eax
365         mov     %r8, %rcx
366         sar     %cl, %eax
367         test    %eax, %eax
368         jz      L(return_null)
370         bsr     %eax, %eax
371         add     %rdi, %rax
372         add     %r8, %rax
373         ret
375         .p2align 4
376 L(length_less16_part2_return):
377         bsr     %eax, %eax
378         lea     16(%rax, %rdi), %rax
379         ret
381 END (memrchr)
382 strong_alias (memrchr, __memrchr)