Improve 64 bit strcat functions with SSE2/SSSE3
[platform/upstream/glibc.git] / sysdeps / x86_64 / multiarch / strlen-no-bsf.S
1 /* strlen SSE2 without bsf
2    Copyright (C) 2010, 2011 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, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #if (defined SHARED || defined USE_AS_STRCAT) && !defined NOT_IN_libc
22
23 # ifndef USE_AS_STRCAT
24
25 #  include <sysdep.h>
26
27 #  define RETURN ret
28
29         .section .text.sse2,"ax",@progbits
30 ENTRY (__strlen_no_bsf)
31 # endif
32         xor     %eax, %eax
33         cmpb    $0, (%rdi)
34         jz      L(exit_tail0)
35         cmpb    $0, 1(%rdi)
36         jz      L(exit_tail1)
37         cmpb    $0, 2(%rdi)
38         jz      L(exit_tail2)
39         cmpb    $0, 3(%rdi)
40         jz      L(exit_tail3)
41         cmpb    $0, 4(%rdi)
42         jz      L(exit_tail4)
43         cmpb    $0, 5(%rdi)
44         jz      L(exit_tail5)
45         cmpb    $0, 6(%rdi)
46         jz      L(exit_tail6)
47         cmpb    $0, 7(%rdi)
48         jz      L(exit_tail7)
49         cmpb    $0, 8(%rdi)
50         jz      L(exit_tail8)
51         cmpb    $0, 9(%rdi)
52         jz      L(exit_tail9)
53         cmpb    $0, 10(%rdi)
54         jz      L(exit_tail10)
55         cmpb    $0, 11(%rdi)
56         jz      L(exit_tail11)
57         cmpb    $0, 12(%rdi)
58         jz      L(exit_tail12)
59         cmpb    $0, 13(%rdi)
60         jz      L(exit_tail13)
61         cmpb    $0, 14(%rdi)
62         jz      L(exit_tail14)
63         cmpb    $0, 15(%rdi)
64         jz      L(exit_tail15)
65         pxor    %xmm0, %xmm0
66         mov     %rdi, %rcx
67         mov     %rdi, %rax
68         and     $-16, %rax
69         add     $16, %rax
70         add     $16, %rcx
71
72         pcmpeqb (%rax), %xmm0
73         pmovmskb %xmm0, %edx
74         pxor    %xmm1, %xmm1
75         test    %edx, %edx
76         lea     16(%rax), %rax
77         jnz     L(exit)
78
79         pcmpeqb (%rax), %xmm1
80         pmovmskb %xmm1, %edx
81         pxor    %xmm2, %xmm2
82         test    %edx, %edx
83         lea     16(%rax), %rax
84         jnz     L(exit)
85
86
87         pcmpeqb (%rax), %xmm2
88         pmovmskb %xmm2, %edx
89         pxor    %xmm3, %xmm3
90         test    %edx, %edx
91         lea     16(%rax), %rax
92         jnz     L(exit)
93
94         pcmpeqb (%rax), %xmm3
95         pmovmskb %xmm3, %edx
96         test    %edx, %edx
97         lea     16(%rax), %rax
98         jnz     L(exit)
99
100         pcmpeqb (%rax), %xmm0
101         pmovmskb %xmm0, %edx
102         test    %edx, %edx
103         lea     16(%rax), %rax
104         jnz     L(exit)
105
106         pcmpeqb (%rax), %xmm1
107         pmovmskb %xmm1, %edx
108         test    %edx, %edx
109         lea     16(%rax), %rax
110         jnz     L(exit)
111
112         pcmpeqb (%rax), %xmm2
113         pmovmskb %xmm2, %edx
114         test    %edx, %edx
115         lea     16(%rax), %rax
116         jnz     L(exit)
117
118         pcmpeqb (%rax), %xmm3
119         pmovmskb %xmm3, %edx
120         test    %edx, %edx
121         lea     16(%rax), %rax
122         jnz     L(exit)
123
124         pcmpeqb (%rax), %xmm0
125         pmovmskb %xmm0, %edx
126         test    %edx, %edx
127         lea     16(%rax), %rax
128         jnz     L(exit)
129
130         pcmpeqb (%rax), %xmm1
131         pmovmskb %xmm1, %edx
132         test    %edx, %edx
133         lea     16(%rax), %rax
134         jnz     L(exit)
135
136         pcmpeqb (%rax), %xmm2
137         pmovmskb %xmm2, %edx
138         test    %edx, %edx
139         lea     16(%rax), %rax
140         jnz     L(exit)
141
142         pcmpeqb (%rax), %xmm3
143         pmovmskb %xmm3, %edx
144         test    %edx, %edx
145         lea     16(%rax), %rax
146         jnz     L(exit)
147
148         pcmpeqb (%rax), %xmm0
149         pmovmskb %xmm0, %edx
150         test    %edx, %edx
151         lea     16(%rax), %rax
152         jnz     L(exit)
153
154         pcmpeqb (%rax), %xmm1
155         pmovmskb %xmm1, %edx
156         test    %edx, %edx
157         lea     16(%rax), %rax
158         jnz     L(exit)
159
160         pcmpeqb (%rax), %xmm2
161         pmovmskb %xmm2, %edx
162         test    %edx, %edx
163         lea     16(%rax), %rax
164         jnz     L(exit)
165
166         pcmpeqb (%rax), %xmm3
167         pmovmskb %xmm3, %edx
168         test    %edx, %edx
169         lea     16(%rax), %rax
170         jnz     L(exit)
171
172         and     $-0x40, %rax
173 L(aligned_64):
174         pcmpeqb (%rax), %xmm0
175         pcmpeqb 16(%rax), %xmm1
176         pcmpeqb 32(%rax), %xmm2
177         pcmpeqb 48(%rax), %xmm3
178         pmovmskb %xmm0, %edx
179         pmovmskb %xmm1, %r11d
180         pmovmskb %xmm2, %r10d
181         pmovmskb %xmm3, %r9d
182         or      %edx, %r9d
183         or      %r11d, %r9d
184         or      %r10d, %r9d
185         lea     64(%rax), %rax
186         jz      L(aligned_64)
187
188         test    %edx, %edx
189         jnz     L(aligned_64_exit_16)
190         test    %r11d, %r11d
191         jnz     L(aligned_64_exit_32)
192         test    %r10d, %r10d
193         jnz     L(aligned_64_exit_48)
194 L(aligned_64_exit_64):
195         pmovmskb %xmm3, %edx
196         jmp     L(aligned_64_exit)
197 L(aligned_64_exit_48):
198         lea     -16(%rax), %rax
199         mov     %r10d, %edx
200         jmp     L(aligned_64_exit)
201 L(aligned_64_exit_32):
202         lea     -32(%rax), %rax
203         mov     %r11d, %edx
204         jmp     L(aligned_64_exit)
205 L(aligned_64_exit_16):
206         lea     -48(%rax), %rax
207 L(aligned_64_exit):
208 L(exit):
209         sub     %rcx, %rax
210         test    %dl, %dl
211         jz      L(exit_high)
212         test    $0x01, %dl
213         jnz     L(exit_tail0)
214
215         test    $0x02, %dl
216         jnz     L(exit_tail1)
217
218         test    $0x04, %dl
219         jnz     L(exit_tail2)
220
221         test    $0x08, %dl
222         jnz     L(exit_tail3)
223
224         test    $0x10, %dl
225         jnz     L(exit_tail4)
226
227         test    $0x20, %dl
228         jnz     L(exit_tail5)
229
230         test    $0x40, %dl
231         jnz     L(exit_tail6)
232         add     $7, %eax
233 L(exit_tail0):
234         RETURN
235
236 L(exit_high):
237         add     $8, %eax
238         test    $0x01, %dh
239         jnz     L(exit_tail0)
240
241         test    $0x02, %dh
242         jnz     L(exit_tail1)
243
244         test    $0x04, %dh
245         jnz     L(exit_tail2)
246
247         test    $0x08, %dh
248         jnz     L(exit_tail3)
249
250         test    $0x10, %dh
251         jnz     L(exit_tail4)
252
253         test    $0x20, %dh
254         jnz     L(exit_tail5)
255
256         test    $0x40, %dh
257         jnz     L(exit_tail6)
258         add     $7, %eax
259         RETURN
260         .p2align 4
261 L(exit_tail1):
262         add     $1, %eax
263         RETURN
264
265 L(exit_tail2):
266         add     $2, %eax
267         RETURN
268
269 L(exit_tail3):
270         add     $3, %eax
271         RETURN
272
273 L(exit_tail4):
274         add     $4, %eax
275         RETURN
276
277 L(exit_tail5):
278         add     $5, %eax
279         RETURN
280 L(exit_tail6):
281         add     $6, %eax
282         RETURN
283 L(exit_tail7):
284         add     $7, %eax
285         RETURN
286 L(exit_tail8):
287         add     $8, %eax
288         RETURN
289 L(exit_tail9):
290         add     $9, %eax
291         RETURN
292 L(exit_tail10):
293         add     $10, %eax
294         RETURN
295 L(exit_tail11):
296         add     $11, %eax
297         RETURN
298 L(exit_tail12):
299         add     $12, %eax
300         RETURN
301 L(exit_tail13):
302         add     $13, %eax
303         RETURN
304 L(exit_tail14):
305         add     $14, %eax
306         RETURN
307 L(exit_tail15):
308         add     $15, %eax
309 # ifndef USE_AS_STRCAT
310         RETURN
311 END (__strlen_no_bsf)
312 # endif
313 #endif