Improve 64 bit strcat functions with SSE2/SSSE3
[platform/upstream/glibc.git] / sysdeps / x86_64 / multiarch / strlen-sse2-pminub.S
1 /* strlen SSE2
2    Copyright (C) 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 NOT_IN_libc && (defined SHARED || defined USE_AS_STRCAT)
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_sse2_pminub)
31
32 # endif
33         xor     %rax, %rax
34         mov     %edi, %ecx
35         and     $0x3f, %ecx
36         pxor    %xmm0, %xmm0
37         cmp     $0x30, %ecx
38         ja      L(next)
39         movdqu  (%rdi), %xmm1
40         pcmpeqb %xmm1, %xmm0
41         pmovmskb %xmm0, %edx
42         test    %edx, %edx
43         jnz     L(exit_less16)
44         mov     %rdi, %rax
45         and     $-16, %rax
46         jmp     L(align16_start)
47 L(next):
48         mov     %rdi, %rax
49         and     $-16, %rax
50         pcmpeqb (%rax), %xmm0
51         mov     $-1, %r10d
52         sub     %rax, %rcx
53         shl     %cl, %r10d
54         pmovmskb %xmm0, %edx
55         and     %r10d, %edx
56         jnz     L(exit)
57 L(align16_start):
58         pxor    %xmm0, %xmm0
59         pxor    %xmm1, %xmm1
60         pxor    %xmm2, %xmm2
61         pxor    %xmm3, %xmm3
62         pcmpeqb 16(%rax), %xmm0
63         pmovmskb %xmm0, %edx
64         test    %edx, %edx
65         jnz     L(exit16)
66
67         pcmpeqb 32(%rax), %xmm1
68         pmovmskb %xmm1, %edx
69         test    %edx, %edx
70         jnz     L(exit32)
71
72         pcmpeqb 48(%rax), %xmm2
73         pmovmskb %xmm2, %edx
74         test    %edx, %edx
75         jnz     L(exit48)
76
77         pcmpeqb 64(%rax), %xmm3
78         pmovmskb %xmm3, %edx
79         test    %edx, %edx
80         jnz     L(exit64)
81
82         pcmpeqb 80(%rax), %xmm0
83         add     $64, %rax
84         pmovmskb %xmm0, %edx
85         test    %edx, %edx
86         jnz     L(exit16)
87
88         pcmpeqb 32(%rax), %xmm1
89         pmovmskb %xmm1, %edx
90         test    %edx, %edx
91         jnz     L(exit32)
92
93         pcmpeqb 48(%rax), %xmm2
94         pmovmskb %xmm2, %edx
95         test    %edx, %edx
96         jnz     L(exit48)
97
98         pcmpeqb 64(%rax), %xmm3
99         pmovmskb %xmm3, %edx
100         test    %edx, %edx
101         jnz     L(exit64)
102
103         pcmpeqb 80(%rax), %xmm0
104         add     $64, %rax
105         pmovmskb %xmm0, %edx
106         test    %edx, %edx
107         jnz     L(exit16)
108
109         pcmpeqb 32(%rax), %xmm1
110         pmovmskb %xmm1, %edx
111         test    %edx, %edx
112         jnz     L(exit32)
113
114         pcmpeqb 48(%rax), %xmm2
115         pmovmskb %xmm2, %edx
116         test    %edx, %edx
117         jnz     L(exit48)
118
119         pcmpeqb 64(%rax), %xmm3
120         pmovmskb %xmm3, %edx
121         test    %edx, %edx
122         jnz     L(exit64)
123
124         pcmpeqb 80(%rax), %xmm0
125         add     $64, %rax
126         pmovmskb %xmm0, %edx
127         test    %edx, %edx
128         jnz     L(exit16)
129
130         pcmpeqb 32(%rax), %xmm1
131         pmovmskb %xmm1, %edx
132         test    %edx, %edx
133         jnz     L(exit32)
134
135         pcmpeqb 48(%rax), %xmm2
136         pmovmskb %xmm2, %edx
137         test    %edx, %edx
138         jnz     L(exit48)
139
140         pcmpeqb 64(%rax), %xmm3
141         pmovmskb %xmm3, %edx
142         test    %edx, %edx
143         jnz     L(exit64)
144         
145
146         test    $0x3f, %rax
147         jz      L(align64_loop)
148
149         pcmpeqb 80(%rax), %xmm0
150         add     $80, %rax
151         pmovmskb %xmm0, %edx
152         test    %edx, %edx
153         jnz     L(exit)
154
155         test    $0x3f, %rax
156         jz      L(align64_loop)
157
158         pcmpeqb 16(%rax), %xmm1
159         add     $16, %rax
160         pmovmskb %xmm1, %edx
161         test    %edx, %edx
162         jnz     L(exit)
163
164         test    $0x3f, %rax
165         jz      L(align64_loop)
166
167         pcmpeqb 16(%rax), %xmm2
168         add     $16, %rax
169         pmovmskb %xmm2, %edx
170         test    %edx, %edx
171         jnz     L(exit)
172
173         test    $0x3f, %rax
174         jz      L(align64_loop)
175
176         pcmpeqb 16(%rax), %xmm3
177         add     $16, %rax
178         pmovmskb %xmm3, %edx
179         test    %edx, %edx
180         jnz     L(exit)
181
182         add     $16, %rax
183         .p2align 4
184         L(align64_loop):
185         movaps  (%rax), %xmm4
186         pminub  16(%rax),       %xmm4
187         movaps  32(%rax),       %xmm5
188         pminub  48(%rax),       %xmm5
189         add     $64,    %rax
190         pminub  %xmm4,  %xmm5
191         pcmpeqb %xmm0,  %xmm5
192         pmovmskb %xmm5, %edx
193         test    %edx,   %edx
194         jz      L(align64_loop)
195
196
197         pcmpeqb -64(%rax), %xmm0
198         sub     $80,    %rax
199         pmovmskb %xmm0, %edx
200         test    %edx, %edx
201         jnz     L(exit16)
202
203         pcmpeqb 32(%rax), %xmm1
204         pmovmskb %xmm1, %edx
205         test    %edx, %edx
206         jnz     L(exit32)
207
208         pcmpeqb 48(%rax), %xmm2
209         pmovmskb %xmm2, %edx
210         test    %edx, %edx
211         jnz     L(exit48)
212
213         pcmpeqb 64(%rax), %xmm3
214         pmovmskb %xmm3, %edx
215         sub     %rdi, %rax
216         bsf     %rdx, %rdx
217         add     %rdx, %rax
218         add     $64, %rax
219         RETURN
220
221         .p2align 4
222 L(exit):
223         sub     %rdi, %rax
224 L(exit_less16):
225         bsf     %rdx, %rdx
226         add     %rdx, %rax
227         RETURN
228         .p2align 4
229 L(exit16):
230         sub     %rdi, %rax
231         bsf     %rdx, %rdx
232         add     %rdx, %rax
233         add     $16, %rax
234         RETURN
235         .p2align 4
236 L(exit32):
237         sub     %rdi, %rax
238         bsf     %rdx, %rdx
239         add     %rdx, %rax
240         add     $32, %rax
241         RETURN
242         .p2align 4
243 L(exit48):
244         sub     %rdi, %rax
245         bsf     %rdx, %rdx
246         add     %rdx, %rax
247         add     $48, %rax
248         RETURN
249         .p2align 4
250 L(exit64):
251         sub     %rdi, %rax
252         bsf     %rdx, %rdx
253         add     %rdx, %rax
254         add     $64, %rax
255 # ifndef USE_AS_STRCAT
256         RETURN
257
258 END (__strlen_sse2_pminub)
259 # endif
260 #endif