Improve 64 bit strcat functions with SSE2/SSSE3
[platform/upstream/glibc.git] / sysdeps / x86_64 / multiarch / strcat-ssse3.S
1 /* strcat with SSSE3
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 #ifndef NOT_IN_libc
22
23 # include <sysdep.h>
24
25 # ifndef STRCAT
26 #  define STRCAT  __strcat_ssse3
27 # endif
28
29 # define USE_AS_STRCAT
30
31 .text
32 ENTRY (STRCAT)
33 # ifdef USE_AS_STRNCAT
34         mov     %rdx, %r8
35 # endif
36
37 # define RETURN  jmp L(StartStrcpyPart)
38 # include "strlen-no-bsf.S"
39
40 # undef RETURN
41
42 L(StartStrcpyPart):
43         mov     %rsi, %rcx
44         lea     (%rdi, %rax), %rdx
45 # ifdef USE_AS_STRNCAT
46         test    %r8, %r8
47         jz      L(StrncatExit0)
48         cmp     $8, %r8
49         jbe     L(StrncatExit8Bytes)
50 # endif
51         cmpb    $0, (%rcx)
52         jz      L(Exit1)
53         cmpb    $0, 1(%rcx)
54         jz      L(Exit2)
55         cmpb    $0, 2(%rcx)
56         jz      L(Exit3)
57         cmpb    $0, 3(%rcx)
58         jz      L(Exit4)
59         cmpb    $0, 4(%rcx)
60         jz      L(Exit5)
61         cmpb    $0, 5(%rcx)
62         jz      L(Exit6)
63         cmpb    $0, 6(%rcx)
64         jz      L(Exit7)
65         cmpb    $0, 7(%rcx)
66         jz      L(Exit8)
67         cmpb    $0, 8(%rcx)
68         jz      L(Exit9)
69 # ifdef USE_AS_STRNCAT
70         cmp     $16, %r8
71         jb      L(StrncatExit15Bytes)
72 # endif
73         cmpb    $0, 9(%rcx)
74         jz      L(Exit10)
75         cmpb    $0, 10(%rcx)
76         jz      L(Exit11)
77         cmpb    $0, 11(%rcx)
78         jz      L(Exit12)
79         cmpb    $0, 12(%rcx)
80         jz      L(Exit13)
81         cmpb    $0, 13(%rcx)
82         jz      L(Exit14)
83         cmpb    $0, 14(%rcx)
84         jz      L(Exit15)
85         cmpb    $0, 15(%rcx)
86         jz      L(Exit16)
87 # ifdef USE_AS_STRNCAT
88         cmp     $16, %r8
89         je      L(StrncatExit16)
90 #  define USE_AS_STRNCPY
91 # endif
92
93 # include "strcpy-ssse3.S"
94
95         .p2align 4
96 L(CopyFrom1To16Bytes):
97         add     %rsi, %rdx
98         add     %rsi, %rcx
99
100         test    %al, %al
101         jz      L(ExitHigh)
102         test    $0x01, %al
103         jnz     L(Exit1)
104         test    $0x02, %al
105         jnz     L(Exit2)
106         test    $0x04, %al
107         jnz     L(Exit3)
108         test    $0x08, %al
109         jnz     L(Exit4)
110         test    $0x10, %al
111         jnz     L(Exit5)
112         test    $0x20, %al
113         jnz     L(Exit6)
114         test    $0x40, %al
115         jnz     L(Exit7)
116         movlpd  (%rcx), %xmm0
117         movlpd  %xmm0, (%rdx)
118         mov     %rdi, %rax
119         ret
120
121         .p2align 4
122 L(ExitHigh):
123         test    $0x01, %ah
124         jnz     L(Exit9)
125         test    $0x02, %ah
126         jnz     L(Exit10)
127         test    $0x04, %ah
128         jnz     L(Exit11)
129         test    $0x08, %ah
130         jnz     L(Exit12)
131         test    $0x10, %ah
132         jnz     L(Exit13)
133         test    $0x20, %ah
134         jnz     L(Exit14)
135         test    $0x40, %ah
136         jnz     L(Exit15)
137         movlpd  (%rcx), %xmm0
138         movlpd  8(%rcx), %xmm1
139         movlpd  %xmm0, (%rdx)
140         movlpd  %xmm1, 8(%rdx)
141         mov     %rdi, %rax
142         ret
143
144         .p2align 4
145 L(StrncatExit1):
146         xor     %ah, %ah
147         movb    %ah, 1(%rdx)
148 L(Exit1):
149         movb    (%rcx), %al
150         movb    %al, (%rdx)
151         mov     %rdi, %rax
152         ret
153
154         .p2align 4
155 L(StrncatExit2):
156         xor     %ah, %ah
157         movb    %ah, 2(%rdx)
158 L(Exit2):
159         movw    (%rcx), %ax
160         movw    %ax, (%rdx)
161         mov     %rdi, %rax
162         ret
163
164         .p2align 4
165 L(StrncatExit3):
166         xor     %ah, %ah
167         movb    %ah, 3(%rdx)
168 L(Exit3):
169         movw    (%rcx), %ax
170         movw    %ax, (%rdx)
171         movb    2(%rcx), %al
172         movb    %al, 2(%rdx)
173         mov     %rdi, %rax
174         ret
175
176         .p2align 4
177 L(StrncatExit4):
178         xor     %ah, %ah
179         movb    %ah, 4(%rdx)
180 L(Exit4):
181         mov     (%rcx), %eax
182         mov     %eax, (%rdx)
183         mov     %rdi, %rax
184         ret
185
186         .p2align 4
187 L(StrncatExit5):
188         xor     %ah, %ah
189         movb    %ah, 5(%rdx)
190 L(Exit5):
191         mov     (%rcx), %eax
192         mov     %eax, (%rdx)
193         movb    4(%rcx), %al
194         movb    %al, 4(%rdx)
195         mov     %rdi, %rax
196         ret
197
198         .p2align 4
199 L(StrncatExit6):
200         xor     %ah, %ah
201         movb    %ah, 6(%rdx)
202 L(Exit6):
203         mov     (%rcx), %eax
204         mov     %eax, (%rdx)
205         movw    4(%rcx), %ax
206         movw    %ax, 4(%rdx)
207         mov     %rdi, %rax
208         ret
209
210         .p2align 4
211 L(StrncatExit7):
212         xor     %ah, %ah
213         movb    %ah, 7(%rdx)
214 L(Exit7):
215         mov     (%rcx), %eax
216         mov     %eax, (%rdx)
217         mov     3(%rcx), %eax
218         mov     %eax, 3(%rdx)
219         mov     %rdi, %rax
220         ret
221
222         .p2align 4
223 L(StrncatExit8):
224         xor     %ah, %ah
225         movb    %ah, 8(%rdx)
226 L(Exit8):
227         movlpd  (%rcx), %xmm0
228         movlpd  %xmm0, (%rdx)
229         mov     %rdi, %rax
230         ret
231
232         .p2align 4
233 L(StrncatExit9):
234         xor     %ah, %ah
235         movb    %ah, 9(%rdx)
236 L(Exit9):
237         movlpd  (%rcx), %xmm0
238         movlpd  %xmm0, (%rdx)
239         movb    8(%rcx), %al
240         movb    %al, 8(%rdx)
241         mov     %rdi, %rax
242         ret
243
244         .p2align 4
245 L(StrncatExit10):
246         xor     %ah, %ah
247         movb    %ah, 10(%rdx)
248 L(Exit10):
249         movlpd  (%rcx), %xmm0
250         movlpd  %xmm0, (%rdx)
251         movw    8(%rcx), %ax
252         movw    %ax, 8(%rdx)
253         mov     %rdi, %rax
254         ret
255
256         .p2align 4
257 L(StrncatExit11):
258         xor     %ah, %ah
259         movb    %ah, 11(%rdx)
260 L(Exit11):
261         movlpd  (%rcx), %xmm0
262         movlpd  %xmm0, (%rdx)
263         mov     7(%rcx), %eax
264         mov     %eax, 7(%rdx)
265         mov     %rdi, %rax
266         ret
267
268         .p2align 4
269 L(StrncatExit12):
270         xor     %ah, %ah
271         movb    %ah, 12(%rdx)
272 L(Exit12):
273         movlpd  (%rcx), %xmm0
274         movlpd  %xmm0, (%rdx)
275         mov     8(%rcx), %eax
276         mov     %eax, 8(%rdx)
277         mov     %rdi, %rax
278         ret
279
280         .p2align 4
281 L(StrncatExit13):
282         xor     %ah, %ah
283         movb    %ah, 13(%rdx)
284 L(Exit13):
285         movlpd  (%rcx), %xmm0
286         movlpd  %xmm0, (%rdx)
287         movlpd  5(%rcx), %xmm1
288         movlpd  %xmm1, 5(%rdx)
289         mov     %rdi, %rax
290         ret
291
292         .p2align 4
293 L(StrncatExit14):
294         xor     %ah, %ah
295         movb    %ah, 14(%rdx)
296 L(Exit14):
297         movlpd  (%rcx), %xmm0
298         movlpd  %xmm0, (%rdx)
299         movlpd  6(%rcx), %xmm1
300         movlpd  %xmm1, 6(%rdx)
301         mov     %rdi, %rax
302         ret
303
304         .p2align 4
305 L(StrncatExit15):
306         xor     %ah, %ah
307         movb    %ah, 15(%rdx)
308 L(Exit15):
309         movlpd  (%rcx), %xmm0
310         movlpd  %xmm0, (%rdx)
311         movlpd  7(%rcx), %xmm1
312         movlpd  %xmm1, 7(%rdx)
313         mov     %rdi, %rax
314         ret
315
316         .p2align 4
317 L(StrncatExit16):
318         xor     %ah, %ah
319         movb    %ah, 16(%rdx)
320 L(Exit16):
321         movlpd  (%rcx), %xmm0
322         movlpd  8(%rcx), %xmm1
323         movlpd  %xmm0, (%rdx)
324         movlpd  %xmm1, 8(%rdx)
325         mov     %rdi, %rax
326         ret
327
328 # ifdef USE_AS_STRNCPY
329
330         .p2align 4
331 L(CopyFrom1To16BytesCase2):
332         add     $16, %r8
333         add     %rsi, %rcx
334         lea     (%rsi, %rdx), %rsi
335         lea     -9(%r8), %rdx
336         and     $1<<7, %dh
337         or      %al, %dh
338         test    %dh, %dh
339         lea     (%rsi), %rdx
340         jz      L(ExitHighCase2)
341
342         test    $0x01, %al
343         jnz     L(Exit1)
344         cmp     $1, %r8
345         je      L(StrncatExit1)
346         test    $0x02, %al
347         jnz     L(Exit2)
348         cmp     $2, %r8
349         je      L(StrncatExit2)
350         test    $0x04, %al
351         jnz     L(Exit3)
352         cmp     $3, %r8
353         je      L(StrncatExit3)
354         test    $0x08, %al
355         jnz     L(Exit4)
356         cmp     $4, %r8
357         je      L(StrncatExit4)
358         test    $0x10, %al
359         jnz     L(Exit5)
360         cmp     $5, %r8
361         je      L(StrncatExit5)
362         test    $0x20, %al
363         jnz     L(Exit6)
364         cmp     $6, %r8
365         je      L(StrncatExit6)
366         test    $0x40, %al
367         jnz     L(Exit7)
368         cmp     $7, %r8
369         je      L(StrncatExit7)
370         movlpd  (%rcx), %xmm0
371         movlpd  %xmm0, (%rdx)
372         lea     7(%rdx), %rax
373         cmpb    $1, (%rax)
374         sbb     $-1, %rax
375         xor     %cl, %cl
376         movb    %cl, (%rax)
377         mov     %rdi, %rax
378         ret
379
380         .p2align 4
381 L(ExitHighCase2):
382         test    $0x01, %ah
383         jnz     L(Exit9)
384         cmp     $9, %r8
385         je      L(StrncatExit9)
386         test    $0x02, %ah
387         jnz     L(Exit10)
388         cmp     $10, %r8
389         je      L(StrncatExit10)
390         test    $0x04, %ah
391         jnz     L(Exit11)
392         cmp     $11, %r8
393         je      L(StrncatExit11)
394         test    $0x8, %ah
395         jnz     L(Exit12)
396         cmp     $12, %r8
397         je      L(StrncatExit12)
398         test    $0x10, %ah
399         jnz     L(Exit13)
400         cmp     $13, %r8
401         je      L(StrncatExit13)
402         test    $0x20, %ah
403         jnz     L(Exit14)
404         cmp     $14, %r8
405         je      L(StrncatExit14)
406         test    $0x40, %ah
407         jnz     L(Exit15)
408         cmp     $15, %r8
409         je      L(StrncatExit15)
410         movlpd  (%rcx), %xmm0
411         movlpd  %xmm0, (%rdx)
412         movlpd  8(%rcx), %xmm1
413         movlpd  %xmm1, 8(%rdx)
414         mov     %rdi, %rax
415         ret
416
417 L(CopyFrom1To16BytesCase2OrCase3):
418         test    %rax, %rax
419         jnz     L(CopyFrom1To16BytesCase2)
420
421         .p2align 4
422 L(CopyFrom1To16BytesCase3):
423         add     $16, %r8
424         add     %rsi, %rdx
425         add     %rsi, %rcx
426
427         cmp     $8, %r8
428         ja      L(ExitHighCase3)
429         cmp     $1, %r8
430         je      L(StrncatExit1)
431         cmp     $2, %r8
432         je      L(StrncatExit2)
433         cmp     $3, %r8
434         je      L(StrncatExit3)
435         cmp     $4, %r8
436         je      L(StrncatExit4)
437         cmp     $5, %r8
438         je      L(StrncatExit5)
439         cmp     $6, %r8
440         je      L(StrncatExit6)
441         cmp     $7, %r8
442         je      L(StrncatExit7)
443         movlpd  (%rcx), %xmm0
444         movlpd  %xmm0, (%rdx)
445         xor     %ah, %ah
446         movb    %ah, 8(%rdx)
447         mov     %rdi, %rax
448         ret
449
450         .p2align 4
451 L(ExitHighCase3):
452         cmp     $9, %r8
453         je      L(StrncatExit9)
454         cmp     $10, %r8
455         je      L(StrncatExit10)
456         cmp     $11, %r8
457         je      L(StrncatExit11)
458         cmp     $12, %r8
459         je      L(StrncatExit12)
460         cmp     $13, %r8
461         je      L(StrncatExit13)
462         cmp     $14, %r8
463         je      L(StrncatExit14)
464         cmp     $15, %r8
465         je      L(StrncatExit15)
466         movlpd  (%rcx), %xmm0
467         movlpd  %xmm0, (%rdx)
468         movlpd  8(%rcx), %xmm1
469         movlpd  %xmm1, 8(%rdx)
470         xor     %ah, %ah
471         movb    %ah, 16(%rdx)
472         mov     %rdi, %rax
473         ret
474
475         .p2align 4
476 L(StrncatExit0):
477         mov     %rdi, %rax
478         ret
479
480         .p2align 4
481 L(StrncatExit15Bytes):
482         cmp     $9, %r8
483         je      L(StrncatExit9)
484         cmpb    $0, 9(%rcx)
485         jz      L(Exit10)
486         cmp     $10, %r8
487         je      L(StrncatExit10)
488         cmpb    $0, 10(%rcx)
489         jz      L(Exit11)
490         cmp     $11, %r8
491         je      L(StrncatExit11)
492         cmpb    $0, 11(%rcx)
493         jz      L(Exit12)
494         cmp     $12, %r8
495         je      L(StrncatExit12)
496         cmpb    $0, 12(%rcx)
497         jz      L(Exit13)
498         cmp     $13, %r8
499         je      L(StrncatExit13)
500         cmpb    $0, 13(%rcx)
501         jz      L(Exit14)
502         cmp     $14, %r8
503         je      L(StrncatExit14)
504         movlpd  (%rcx), %xmm0
505         movlpd  %xmm0, (%rdx)
506         movlpd  7(%rcx), %xmm1
507         movlpd  %xmm1, 7(%rdx)
508         lea     14(%rdx), %rax
509         cmpb    $1, (%rax)
510         sbb     $-1, %rax
511         xor     %cl, %cl
512         movb    %cl, (%rax)
513         mov     %rdi, %rax
514         ret
515
516         .p2align 4
517 L(StrncatExit8Bytes):
518         cmpb    $0, (%rcx)
519         jz      L(Exit1)
520         cmp     $1, %r8
521         je      L(StrncatExit1)
522         cmpb    $0, 1(%rcx)
523         jz      L(Exit2)
524         cmp     $2, %r8
525         je      L(StrncatExit2)
526         cmpb    $0, 2(%rcx)
527         jz      L(Exit3)
528         cmp     $3, %r8
529         je      L(StrncatExit3)
530         cmpb    $0, 3(%rcx)
531         jz      L(Exit4)
532         cmp     $4, %r8
533         je      L(StrncatExit4)
534         cmpb    $0, 4(%rcx)
535         jz      L(Exit5)
536         cmp     $5, %r8
537         je      L(StrncatExit5)
538         cmpb    $0, 5(%rcx)
539         jz      L(Exit6)
540         cmp     $6, %r8
541         je      L(StrncatExit6)
542         cmpb    $0, 6(%rcx)
543         jz      L(Exit7)
544         cmp     $7, %r8
545         je      L(StrncatExit7)
546         movlpd  (%rcx), %xmm0
547         movlpd  %xmm0, (%rdx)
548         lea     7(%rdx), %rax
549         cmpb    $1, (%rax)
550         sbb     $-1, %rax
551         xor     %cl, %cl
552         movb    %cl, (%rax)
553         mov     %rdi, %rax
554         ret
555
556 # endif
557 END (STRCAT)
558 #endif
559