SSSE3 strcpy/stpcpy for x86-64
[glibc.git] / sysdeps / x86_64 / multiarch / strcpy.S
blobbbc9979e0c0f1ce5833b021861240147631e08c3
1 /* strcpy with SSSE3
2    Copyright (C) 2009 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, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
21 #include <sysdep.h>
22 #include <ifunc-defines.h>
24 #if !defined (USE_AS_STPCPY) && !defined (USE_AS_STRNCPY)
25 # ifndef STRCPY
26 #  define STRCPY strcpy
27 # endif
28 #endif
30 #ifdef USE_AS_STPCPY
31 # ifdef USE_AS_STRNCPY
32 #  define STRCPY_SSSE3  __stpncpy_ssse3
33 #  define STRCPY_SSE2   __stpncpy_sse2
34 #  define __GI_STRCPY   __GI_stpncpy
35 # else
36 #  define STRCPY_SSSE3  __stpcpy_ssse3
37 #  define STRCPY_SSE2   __stpcpy_sse2
38 #  define __GI_STRCPY   __GI_stpcpy
39 #  define __GI___STRCPY __GI___stpcpy
40 # endif
41 #else
42 # ifdef USE_AS_STRNCPY
43 #  define STRCPY_SSSE3  __strncpy_ssse3
44 #  define STRCPY_SSE2   __strncpy_sse2
45 #  define __GI_STRCPY   __GI_strncpy
46 # else
47 #  define STRCPY_SSSE3  __strcpy_ssse3
48 #  define STRCPY_SSE2   __strcpy_sse2
49 #  define __GI_STRCPY   __GI_strcpy
50 # endif
51 #endif
53 #ifndef LABEL
54 #define LABEL(l) L(l)
55 #endif
57 /* Define multiple versions only for the definition in libc.  */
58 #ifndef NOT_IN_libc
59         .text
60 ENTRY(STRCPY)
61         .type   STRCPY, @gnu_indirect_function
62         cmpl    $0, __cpu_features+KIND_OFFSET(%rip)
63         jne     1f
64         call    __init_cpu_features
65 1:      leaq    STRCPY_SSE2(%rip), %rax
66         testl   $(1<<9), __cpu_features+CPUID_OFFSET+COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET(%rip)
67         jz      3f
68 /* Avoid SSSE3 strcpy on Atom since it is slow.  */
69         cmpl    $1, __cpu_features+KIND_OFFSET(%rip)
70         jne     2f
71         cmpl    $6, __cpu_features+FAMILY_OFFSET(%rip)
72         jne     2f
73         cmpl    $28, __cpu_features+MODEL_OFFSET(%rip)
74         jz      3f
75 2:      leaq    STRCPY_SSSE3(%rip), %rax
76 3:      ret
77 END(STRCPY)
79         .section .text.ssse3,"ax",@progbits
80 STRCPY_SSSE3:
81         cfi_startproc
82         CALL_MCOUNT
85  * This implementation uses SSE to copy up to 16 bytes at a time.
86  */
87 #ifdef USE_AS_STRNCPY
88         test    %rdx, %rdx
89         jz      LABEL(strncpy_exitz)
90         mov     %rdx, %r8
91 #else
92         xor     %edx, %edx
93 #endif
94         mov     %esi, %ecx
95         and     $0xfffffffffffffff0, %rsi       /*force rsi 16 byte align*/
96         and     $15, %ecx
97         mov     %rdi, %rax                      /*store return parameter*/
100         pxor    %xmm0, %xmm0                    /* clear %xmm0 */
101         pcmpeqb (%rsi), %xmm0                   /* compare 16 bytes in (%rsi) and %xmm0 for equality, try to find null char*/
102         pmovmskb %xmm0, %edx                    /* move each byte mask of %xmm0 to edx*/
103         shr     %cl, %edx                       /* get real bits left in edx*/
104         test    %edx, %edx                      /* edx must be 0 if there is no null char from rsi+%rcx */
105         jnz     LABEL(less16bytes)
107 #ifdef USE_AS_STRNCPY
108         lea     -16(%r8,%rcx), %r11
109         cmp     $0, %r11
110         jle     LABEL(less16bytes)              /* if r8 + rcx <= 16, branch to less16bytes.  */
111 #endif
113         mov     %rcx, %r9
114         or      %edi, %ecx
115         and     $15, %ecx
116         lea     -16(%r9), %r10
117         jz      LABEL(ashr_0)                   /* ecx must be 0 if offset of rsi and rdi is 16 byte align*/
119         neg     %r10                            /* store the rest in rsi aligned 16 bytes for unaligned_exit*/
121         pxor    %xmm0, %xmm0                    /* clear %xmm0, may be polluted by unaligned operation*/
122         pcmpeqb 16(%rsi), %xmm0                 /* compare 16 bytes in (%rsi) and %xmm0 for equality, try to find null char*/
123         pmovmskb %xmm0, %edx
124         test    %edx, %edx
125         jnz     LABEL(less32bytes)
126         /*
127         * at least 16 byte available to fill destination rdi
128         */
129 #ifdef USE_AS_STRNCPY
130         sub     $16, %r8
131         jbe     LABEL(less32bytes_strncpy_truncation)
132 #endif
133         mov     (%rsi, %r9), %rdx
134         mov     %rdx, (%rdi)
135         mov     8(%rsi, %r9), %rdx
136         mov     %rdx, 8(%rdi)
138         /*
139         * so far destatination rdi may be aligned by 16, re-calculate rsi to jump
140         * crossponding case
141         * rcx is offset of rsi
142         * rax is offset of rdi
143         */
145         and     $0xfffffffffffffff0, %rdi       /* force rdi 16 byte align */
146         mov     %rax, %rdx                      /* rax store orignal rdi */
147         xor     %rdi, %rdx                      /* equal to and $15, %rdx */
148 #ifdef USE_AS_STRNCPY
149         add     %rdx, %r8
150 #endif
152         add     $16, %rdi                       /* next 16 bytes for rdi */
153         sub     %rdx, %r9
155         lea     16(%r9, %rsi), %rsi             /*re-calculate rsi by (16 - rdx)+ rcx */
156         mov     %esi, %ecx                      /*store offset of rsi */
157         and     $0xfffffffffffffff0, %rsi       /* force rsi 16 byte align */
159         and     $15, %ecx                       /* ecx must be 0 if rdx is equal to rcx*/
160         jz      LABEL(ashr_0)
162         lea     -16(%rcx), %r10
163         mov     %rcx, %r9
164         neg     %r10
165         lea     LABEL(unaligned_table)(%rip), %r11
166         movslq  (%r11, %rcx,4), %rcx
167         lea     (%r11, %rcx), %rcx
168         jmp     *%rcx
170  /*
171  * The following cases will be handled by ashr_0 & ashr_0_start
172  *  rcx(offset of rsi)  rax(offset of rdi)  relative offset  corresponding case
173  *      0                   0             0              ashr_0
174  *      n(1~15)      n(1~15)       0             ashr_0_start
176  */
177         .p2align 5
178 LABEL(ashr_0):
179 #ifdef USE_AS_STRNCPY
180         sub     $16, %r8
181         jbe     LABEL(strncpy_truncation_aligned)
182 #endif
183         movdqa  (%rsi), %xmm1      /* fetch first 16 bytes from rsi */
184         movdqa  %xmm1, (%rdi)      /* store first 16 bytes into rdi */
185         add     $16, %rsi
186         add     $16, %rdi
187         pcmpeqb  (%rsi), %xmm0             /* compare 16 bytes in (%rsi) and %xmm0 for equality, try to find null char */
188         pmovmskb  %xmm0, %edx              /* move each byte mask of %xmm0 to edx*/
190         test    %edx, %edx                /* edx must be 0 if there is no null char in rsi*/
191         jnz     LABEL(aligned_16bytes)
193 LABEL(ashr_0_loop):
194 #ifdef USE_AS_STRNCPY
195         sub     $16, %r8
196         jbe     LABEL(strncpy_truncation_aligned)
197 #endif
198         movdqa  (%rsi, %rcx), %xmm1
199         movdqa  %xmm1, (%rdi, %rcx)
200         add     $16, %rcx
201         pcmpeqb  (%rsi, %rcx), %xmm0
202         pmovmskb  %xmm0, %edx
203         test    %edx, %edx
204         jnz     LABEL(aligned_exit)
206 #ifdef USE_AS_STRNCPY
207         sub     $16, %r8
208         jbe     LABEL(strncpy_truncation_aligned)
209 #endif
210         movdqa  (%rsi, %rcx), %xmm1
211         movdqa  %xmm1, (%rdi, %rcx)
212         add     $16, %rcx
213         pcmpeqb  (%rsi, %rcx), %xmm0
214         pmovmskb  %xmm0, %edx
215         test    %edx, %edx
216         jnz     LABEL(aligned_exit)
218 #ifdef USE_AS_STRNCPY
219         sub     $16, %r8
220         jbe     LABEL(strncpy_truncation_aligned)
221 #endif
222         movdqa  (%rsi, %rcx), %xmm1
223         movdqa  %xmm1, (%rdi, %rcx)
224         add     $16, %rcx
225         pcmpeqb  (%rsi, %rcx), %xmm0
226         pmovmskb  %xmm0, %edx
227         test    %edx, %edx
228         jnz     LABEL(aligned_exit)
230 #ifdef USE_AS_STRNCPY
231         sub     $16, %r8
232         jbe     LABEL(strncpy_truncation_aligned)
233 #endif
234         movdqa  (%rsi, %rcx), %xmm1
235         movdqa  %xmm1, (%rdi, %rcx)
236         add     $16, %rcx
237         pcmpeqb  (%rsi, %rcx), %xmm0
238         pmovmskb  %xmm0, %edx
239         test    %edx, %edx
240         jz      LABEL(ashr_0_loop)
242         jmp     LABEL(aligned_exit)
243         .p2align 4
246  * The following cases will be handled by ashr_15
247  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
248  *      n(15)           n - 15          15((16 - (n -15) + n)%16         ashr_15
250  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
251  */
252         .p2align 4
253 LABEL(ashr_15):
254         xor     %ecx, %ecx                              /*clear ecx */
255 #ifdef USE_AS_STRNCPY
256         cmp     %r10, %r8
257         jbe     LABEL(unaligned_exit)
258 #endif
260         .p2align 4
261 LABEL(ashr_15_use_ssse3):
262         movdqa  16(%rsi, %rcx), %xmm3
263         pcmpeqb %xmm3, %xmm0
264         pmovmskb %xmm0, %edx
265         test    %edx, %edx
266         jnz     LABEL(unaligned_exit)
267 #ifdef USE_AS_STRNCPY
268         sub     $16, %r8
269         jbe     LABEL(strncpy_truncation_unaligned)
270 #endif
272         palignr $15, (%rsi, %rcx), %xmm3
273         movdqa  %xmm3, (%rdi, %rcx)
274         add     $16, %rcx
276 #ifdef USE_AS_STRNCPY
277         cmp     %r10, %r8
278         jbe     LABEL(unaligned_exit)
279 #endif
281         movdqa  16(%rsi, %rcx), %xmm3
282         pcmpeqb %xmm3, %xmm0
283         pmovmskb %xmm0, %edx
284         test    %edx, %edx
285         jnz     LABEL(unaligned_exit)
286 #ifdef USE_AS_STRNCPY
287         sub     $16, %r8
288         jbe     LABEL(strncpy_truncation_unaligned)
289 #endif
291         palignr $15, (%rsi, %rcx), %xmm3
292         movdqa  %xmm3, (%rdi, %rcx)
293         add     $16, %rcx
295 #ifdef USE_AS_STRNCPY
296         cmp     %r10, %r8
297         jbe     LABEL(unaligned_exit)
298 #endif
299         jmp     LABEL(ashr_15_use_ssse3)
302  * The following cases will be handled by ashr_14
303  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
304  *      n(14~15)                n - 14          14((16 - (n -14) + n)%16         ashr_14
306  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
307  */
308         .p2align 4
309 LABEL(ashr_14):
310         xor     %ecx, %ecx                              /*clear ecx */
311 #ifdef USE_AS_STRNCPY
312         cmp     %r10, %r8
313         jbe     LABEL(unaligned_exit)
314 #endif
316         .p2align 4
317 LABEL(ashr_14_use_ssse3):
318         movdqa  16(%rsi, %rcx), %xmm3
319         pcmpeqb %xmm3, %xmm0
320         pmovmskb %xmm0, %edx
321         test    %edx, %edx
322         jnz     LABEL(unaligned_exit)
323 #ifdef USE_AS_STRNCPY
324         sub     $16, %r8
325         jbe     LABEL(strncpy_truncation_unaligned)
326 #endif
328         palignr $14, (%rsi, %rcx), %xmm3
329         movdqa  %xmm3, (%rdi, %rcx)
330         add     $16, %rcx
332 #ifdef USE_AS_STRNCPY
333         cmp     %r10, %r8
334         jbe     LABEL(unaligned_exit)
335 #endif
337         movdqa  16(%rsi, %rcx), %xmm3
338         pcmpeqb %xmm3, %xmm0
339         pmovmskb %xmm0, %edx
340         test    %edx, %edx
341         jnz     LABEL(unaligned_exit)
342 #ifdef USE_AS_STRNCPY
343         sub     $16, %r8
344         jbe     LABEL(strncpy_truncation_unaligned)
345 #endif
347         palignr $14, (%rsi, %rcx), %xmm3
348         movdqa  %xmm3, (%rdi, %rcx)
349         add     $16, %rcx
351 #ifdef USE_AS_STRNCPY
352         cmp     %r10, %r8
353         jbe     LABEL(unaligned_exit)
354 #endif
355         jmp     LABEL(ashr_14_use_ssse3)
358  * The following cases will be handled by ashr_13
359  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
360  *      n(13~15)                n - 13          13((16 - (n -13) + n)%16         ashr_13
362  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
363  */
364         .p2align 4
365 LABEL(ashr_13):
366         xor     %ecx, %ecx                              /*clear ecx */
367 #ifdef USE_AS_STRNCPY
368         cmp     %r10, %r8
369         jbe     LABEL(unaligned_exit)
370 #endif
372         .p2align 4
373 LABEL(ashr_13_use_ssse3):
374         movdqa  16(%rsi, %rcx), %xmm3
375         pcmpeqb %xmm3, %xmm0
376         pmovmskb %xmm0, %edx
377         test    %edx, %edx
378         jnz     LABEL(unaligned_exit)
379 #ifdef USE_AS_STRNCPY
380         sub     $16, %r8
381         jbe     LABEL(strncpy_truncation_unaligned)
382 #endif
384         palignr $13, (%rsi, %rcx), %xmm3
385         movdqa  %xmm3, (%rdi, %rcx)
386         add     $16, %rcx
388 #ifdef USE_AS_STRNCPY
389         cmp     %r10, %r8
390         jbe     LABEL(unaligned_exit)
391 #endif
393         movdqa  16(%rsi, %rcx), %xmm3
394         pcmpeqb %xmm3, %xmm0
395         pmovmskb %xmm0, %edx
396         test    %edx, %edx
397         jnz     LABEL(unaligned_exit)
398 #ifdef USE_AS_STRNCPY
399         sub     $16, %r8
400         jbe     LABEL(strncpy_truncation_unaligned)
401 #endif
403         palignr $13, (%rsi, %rcx), %xmm3
404         movdqa  %xmm3, (%rdi, %rcx)
405         add     $16, %rcx
407 #ifdef USE_AS_STRNCPY
408         cmp     %r10, %r8
409         jbe     LABEL(unaligned_exit)
410 #endif
411         jmp     LABEL(ashr_13_use_ssse3)
414  * The following cases will be handled by ashr_12
415  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
416  *      n(12~15)                n - 12          12((16 - (n -12) + n)%16         ashr_12
418  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
419  */
420         .p2align 4
421 LABEL(ashr_12):
422         xor     %ecx, %ecx                              /*clear ecx */
423 #ifdef USE_AS_STRNCPY
424         cmp     %r10, %r8
425         jbe     LABEL(unaligned_exit)
426 #endif
428         .p2align 4
429 LABEL(ashr_12_use_ssse3):
430         movdqa  16(%rsi, %rcx), %xmm3
431         pcmpeqb %xmm3, %xmm0
432         pmovmskb %xmm0, %edx
433         test    %edx, %edx
434         jnz     LABEL(unaligned_exit)
435 #ifdef USE_AS_STRNCPY
436         sub     $16, %r8
437         jbe     LABEL(strncpy_truncation_unaligned)
438 #endif
440         palignr $12, (%rsi, %rcx), %xmm3
441         movdqa  %xmm3, (%rdi, %rcx)
442         add     $16, %rcx
444 #ifdef USE_AS_STRNCPY
445         cmp     %r10, %r8
446         jbe     LABEL(unaligned_exit)
447 #endif
449         movdqa  16(%rsi, %rcx), %xmm3
450         pcmpeqb %xmm3, %xmm0
451         pmovmskb %xmm0, %edx
452         test    %edx, %edx
453         jnz     LABEL(unaligned_exit)
454 #ifdef USE_AS_STRNCPY
455         sub     $16, %r8
456         jbe     LABEL(strncpy_truncation_unaligned)
457 #endif
459         palignr $12, (%rsi, %rcx), %xmm3
460         movdqa  %xmm3, (%rdi, %rcx)
461         add     $16, %rcx
463 #ifdef USE_AS_STRNCPY
464         cmp     %r10, %r8
465         jbe     LABEL(unaligned_exit)
466 #endif
467         jmp     LABEL(ashr_12_use_ssse3)
470  * The following cases will be handled by ashr_11
471  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
472  *      n(11~15)                n - 11          11((16 - (n -11) + n)%16         ashr_11
474  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
475  */
476         .p2align 4
477 LABEL(ashr_11):
478         xor     %ecx, %ecx                              /*clear ecx */
479 #ifdef USE_AS_STRNCPY
480         cmp     %r10, %r8
481         jbe     LABEL(unaligned_exit)
482 #endif
484         .p2align 4
485 LABEL(ashr_11_use_ssse3):
486         movdqa  16(%rsi, %rcx), %xmm3
487         pcmpeqb %xmm3, %xmm0
488         pmovmskb %xmm0, %edx
489         test    %edx, %edx
490         jnz     LABEL(unaligned_exit)
491 #ifdef USE_AS_STRNCPY
492         sub     $16, %r8
493         jbe     LABEL(strncpy_truncation_unaligned)
494 #endif
496         palignr $11, (%rsi, %rcx), %xmm3
497         movdqa  %xmm3, (%rdi, %rcx)
498         add     $16, %rcx
500 #ifdef USE_AS_STRNCPY
501         cmp     %r10, %r8
502         jbe     LABEL(unaligned_exit)
503 #endif
505         movdqa  16(%rsi, %rcx), %xmm3
506         pcmpeqb %xmm3, %xmm0
507         pmovmskb %xmm0, %edx
508         test    %edx, %edx
509         jnz     LABEL(unaligned_exit)
510 #ifdef USE_AS_STRNCPY
511         sub     $16, %r8
512         jbe     LABEL(strncpy_truncation_unaligned)
513 #endif
515         palignr $11, (%rsi, %rcx), %xmm3
516         movdqa  %xmm3, (%rdi, %rcx)
517         add     $16, %rcx
519 #ifdef USE_AS_STRNCPY
520         cmp     %r10, %r8
521         jbe     LABEL(unaligned_exit)
522 #endif
523         jmp     LABEL(ashr_11_use_ssse3)
526  * The following cases will be handled by ashr_10
527  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
528  *      n(10~15)                n - 10          10((16 - (n -10) + n)%16         ashr_10
530  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
531  */
532         .p2align 4
533 LABEL(ashr_10):
534         xor     %ecx, %ecx                              /*clear ecx */
535 #ifdef USE_AS_STRNCPY
536         cmp     %r10, %r8
537         jbe     LABEL(unaligned_exit)
538 #endif
540         .p2align 4
541 LABEL(ashr_10_use_ssse3):
542         movdqa  16(%rsi, %rcx), %xmm3
543         pcmpeqb %xmm3, %xmm0
544         pmovmskb %xmm0, %edx
545         test    %edx, %edx
546         jnz     LABEL(unaligned_exit)
547 #ifdef USE_AS_STRNCPY
548         sub     $16, %r8
549         jbe     LABEL(strncpy_truncation_unaligned)
550 #endif
552         palignr $10, (%rsi, %rcx), %xmm3
553         movdqa  %xmm3, (%rdi, %rcx)
554         add     $16, %rcx
556 #ifdef USE_AS_STRNCPY
557         cmp     %r10, %r8
558         jbe     LABEL(unaligned_exit)
559 #endif
561         movdqa  16(%rsi, %rcx), %xmm3
562         pcmpeqb %xmm3, %xmm0
563         pmovmskb %xmm0, %edx
564         test    %edx, %edx
565         jnz     LABEL(unaligned_exit)
566 #ifdef USE_AS_STRNCPY
567         sub     $16, %r8
568         jbe     LABEL(strncpy_truncation_unaligned)
569 #endif
571         palignr $10, (%rsi, %rcx), %xmm3
572         movdqa  %xmm3, (%rdi, %rcx)
573         add     $16, %rcx
575 #ifdef USE_AS_STRNCPY
576         cmp     %r10, %r8
577         jbe     LABEL(unaligned_exit)
578 #endif
579         jmp     LABEL(ashr_10_use_ssse3)
582  * The following cases will be handled by ashr_9
583  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
584  *      n(9~15)         n - 9           9((16 - (n -9) + n)%16   ashr_9
586  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
587  */
588         .p2align 4
589 LABEL(ashr_9):
590         xor     %ecx, %ecx                              /*clear ecx */
591 #ifdef USE_AS_STRNCPY
592         cmp     %r10, %r8
593         jbe     LABEL(unaligned_exit)
594 #endif
596         .p2align 4
597 LABEL(ashr_9_use_ssse3):
598         movdqa  16(%rsi, %rcx), %xmm3
599         pcmpeqb %xmm3, %xmm0
600         pmovmskb %xmm0, %edx
601         test    %edx, %edx
602         jnz     LABEL(unaligned_exit)
603 #ifdef USE_AS_STRNCPY
604         sub     $16, %r8
605         jbe     LABEL(strncpy_truncation_unaligned)
606 #endif
608         palignr $9, (%rsi, %rcx), %xmm3
609         movdqa  %xmm3, (%rdi, %rcx)
610         add     $16, %rcx
612 #ifdef USE_AS_STRNCPY
613         cmp     %r10, %r8
614         jbe     LABEL(unaligned_exit)
615 #endif
617         movdqa  16(%rsi, %rcx), %xmm3
618         pcmpeqb %xmm3, %xmm0
619         pmovmskb %xmm0, %edx
620         test    %edx, %edx
621         jnz     LABEL(unaligned_exit)
622 #ifdef USE_AS_STRNCPY
623         sub     $16, %r8
624         jbe     LABEL(strncpy_truncation_unaligned)
625 #endif
627         palignr $9, (%rsi, %rcx), %xmm3
628         movdqa  %xmm3, (%rdi, %rcx)
629         add     $16, %rcx
631 #ifdef USE_AS_STRNCPY
632         cmp     %r10, %r8
633         jbe     LABEL(unaligned_exit)
634 #endif
635         jmp     LABEL(ashr_9_use_ssse3)
638  * The following cases will be handled by ashr_8
639  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
640  *      n(8~15)         n - 8           8((16 - (n -8) + n)%16   ashr_8
642  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
643  */
644         .p2align 4
645 LABEL(ashr_8):
646         xor     %ecx, %ecx                              /*clear ecx */
647 #ifdef USE_AS_STRNCPY
648         cmp     %r10, %r8
649         jbe     LABEL(unaligned_exit)
650 #endif
652         .p2align 4
653 LABEL(ashr_8_use_ssse3):
654         movdqa  16(%rsi, %rcx), %xmm3
655         pcmpeqb %xmm3, %xmm0
656         pmovmskb %xmm0, %edx
657         test    %edx, %edx
658         jnz     LABEL(unaligned_exit)
659 #ifdef USE_AS_STRNCPY
660         sub     $16, %r8
661         jbe     LABEL(strncpy_truncation_unaligned)
662 #endif
664         palignr $8, (%rsi, %rcx), %xmm3
665         movdqa  %xmm3, (%rdi, %rcx)
666         add     $16, %rcx
668 #ifdef USE_AS_STRNCPY
669         cmp     %r10, %r8
670         jbe     LABEL(unaligned_exit)
671 #endif
673         movdqa  16(%rsi, %rcx), %xmm3
674         pcmpeqb %xmm3, %xmm0
675         pmovmskb %xmm0, %edx
676         test    %edx, %edx
677         jnz     LABEL(unaligned_exit)
678 #ifdef USE_AS_STRNCPY
679         sub     $16, %r8
680         jbe     LABEL(strncpy_truncation_unaligned)
681 #endif
683         palignr $8, (%rsi, %rcx), %xmm3
684         movdqa  %xmm3, (%rdi, %rcx)
685         add     $16, %rcx
687 #ifdef USE_AS_STRNCPY
688         cmp     %r10, %r8
689         jbe     LABEL(unaligned_exit)
690 #endif
691         jmp     LABEL(ashr_8_use_ssse3)
694  * The following cases will be handled by ashr_7
695  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
696  *      n(7~15)         n - 7           7((16 - (n -7) + n)%16   ashr_7
698  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
699  */
700         .p2align 4
701 LABEL(ashr_7):
702         xor     %ecx, %ecx                              /*clear ecx */
703 #ifdef USE_AS_STRNCPY
704         cmp     %r10, %r8
705         jbe     LABEL(unaligned_exit)
706 #endif
707         .p2align 4
709 LABEL(ashr_7_use_ssse3):
710         movdqa  16(%rsi, %rcx), %xmm3
711         pcmpeqb %xmm3, %xmm0
712         pmovmskb %xmm0, %edx
713         test    %edx, %edx
714         jnz     LABEL(unaligned_exit)
715 #ifdef USE_AS_STRNCPY
716         sub     $16, %r8
717         jbe     LABEL(strncpy_truncation_unaligned)
718 #endif
720         palignr $7, (%rsi, %rcx), %xmm3
721         movdqa  %xmm3, (%rdi, %rcx)
722         add     $16, %rcx
724 #ifdef USE_AS_STRNCPY
725         cmp     %r10, %r8
726         jbe     LABEL(unaligned_exit)
727 #endif
729         movdqa  16(%rsi, %rcx), %xmm3
730         pcmpeqb %xmm3, %xmm0
731         pmovmskb %xmm0, %edx
732         test    %edx, %edx
733         jnz     LABEL(unaligned_exit)
734 #ifdef USE_AS_STRNCPY
735         sub     $16, %r8
736         jbe     LABEL(strncpy_truncation_unaligned)
737 #endif
739         palignr $7, (%rsi, %rcx), %xmm3
740         movdqa  %xmm3, (%rdi, %rcx)
741         add     $16, %rcx
743 #ifdef USE_AS_STRNCPY
744         cmp     %r10, %r8
745         jbe     LABEL(unaligned_exit)
746 #endif
747         jmp     LABEL(ashr_7_use_ssse3)
750  * The following cases will be handled by ashr_6
751  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
752  *      n(6~15)         n - 6           6((16 - (n -6) + n)%16   ashr_6
754  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
755  */
756         .p2align 4
757 LABEL(ashr_6):
758         xor     %ecx, %ecx                              /*clear ecx */
759 #ifdef USE_AS_STRNCPY
760         cmp     %r10, %r8
761         jbe     LABEL(unaligned_exit)
762 #endif
764         .p2align 4
765 LABEL(ashr_6_use_ssse3):
766         movdqa  16(%rsi, %rcx), %xmm3
767         pcmpeqb %xmm3, %xmm0
768         pmovmskb %xmm0, %edx
769         test    %edx, %edx
770         jnz     LABEL(unaligned_exit)
771 #ifdef USE_AS_STRNCPY
772         sub     $16, %r8
773         jbe     LABEL(strncpy_truncation_unaligned)
774 #endif
776         palignr $6, (%rsi, %rcx), %xmm3
777         movdqa  %xmm3, (%rdi, %rcx)
778         add     $16, %rcx
780 #ifdef USE_AS_STRNCPY
781         cmp     %r10, %r8
782         jbe     LABEL(unaligned_exit)
783 #endif
785         movdqa  16(%rsi, %rcx), %xmm3
786         pcmpeqb %xmm3, %xmm0
787         pmovmskb %xmm0, %edx
788         test    %edx, %edx
789         jnz     LABEL(unaligned_exit)
790 #ifdef USE_AS_STRNCPY
791         sub     $16, %r8
792         jbe     LABEL(strncpy_truncation_unaligned)
793 #endif
795         palignr $6, (%rsi, %rcx), %xmm3
796         movdqa  %xmm3, (%rdi, %rcx)
797         add     $16, %rcx
799 #ifdef USE_AS_STRNCPY
800         cmp     %r10, %r8
801         jbe     LABEL(unaligned_exit)
802 #endif
803         jmp     LABEL(ashr_6_use_ssse3)
805  /*
806  * The following cases will be handled by ashr_5
807  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
808  *      n(5~15)         n - 5           5((16 - (n -5) + n)%16   ashr_5
810  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
811  */
812         .p2align 4
813 LABEL(ashr_5):
814         xor     %ecx, %ecx                              /*clear ecx */
815 #ifdef USE_AS_STRNCPY
816         cmp     %r10, %r8
817         jbe     LABEL(unaligned_exit)
818 #endif
820         .p2align 4
821 LABEL(ashr_5_use_ssse3):
822         movdqa  16(%rsi, %rcx), %xmm3
823         pcmpeqb %xmm3, %xmm0
824         pmovmskb %xmm0, %edx
825         test    %edx, %edx
826         jnz     LABEL(unaligned_exit)
827 #ifdef USE_AS_STRNCPY
828         sub     $16, %r8
829         jbe     LABEL(strncpy_truncation_unaligned)
830 #endif
832         palignr $5, (%rsi, %rcx), %xmm3
833         movdqa  %xmm3, (%rdi, %rcx)
834         add     $16, %rcx
836 #ifdef USE_AS_STRNCPY
837         cmp     %r10, %r8
838         jbe     LABEL(unaligned_exit)
839 #endif
841         movdqa  16(%rsi, %rcx), %xmm3
842         pcmpeqb %xmm3, %xmm0
843         pmovmskb %xmm0, %edx
844         test    %edx, %edx
845         jnz     LABEL(unaligned_exit)
846 #ifdef USE_AS_STRNCPY
847         sub     $16, %r8
848         jbe     LABEL(strncpy_truncation_unaligned)
849 #endif
851         palignr $5, (%rsi, %rcx), %xmm3
852         movdqa  %xmm3, (%rdi, %rcx)
853         add     $16, %rcx
855 #ifdef USE_AS_STRNCPY
856         cmp     %r10, %r8
857         jbe     LABEL(unaligned_exit)
858 #endif
859         jmp     LABEL(ashr_5_use_ssse3)
863  * The following cases will be handled by ashr_4
864  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
865  *      n(4~15)         n - 4           4((16 - (n -4) + n)%16   ashr_4
867  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
868  */
869         .p2align 4
870 LABEL(ashr_4):
871         xor     %ecx, %ecx                              /*clear ecx */
872 #ifdef USE_AS_STRNCPY
873         cmp     %r10, %r8
874         jbe     LABEL(unaligned_exit)
875 #endif
877         .p2align 4
878 LABEL(ashr_4_use_ssse3):
879         movdqa  16(%rsi, %rcx), %xmm3
880         pcmpeqb %xmm3, %xmm0
881         pmovmskb %xmm0, %edx
882         test    %edx, %edx
883         jnz     LABEL(unaligned_exit)
884 #ifdef USE_AS_STRNCPY
885         sub     $16, %r8
886         jbe     LABEL(strncpy_truncation_unaligned)
887 #endif
889         palignr $4, (%rsi, %rcx), %xmm3
890         movdqa  %xmm3, (%rdi, %rcx)
891         add     $16, %rcx
893 #ifdef USE_AS_STRNCPY
894         cmp     %r10, %r8
895         jbe     LABEL(unaligned_exit)
896 #endif
898         movdqa  16(%rsi, %rcx), %xmm3
899         pcmpeqb %xmm3, %xmm0
900         pmovmskb %xmm0, %edx
901         test    %edx, %edx
902         jnz     LABEL(unaligned_exit)
903 #ifdef USE_AS_STRNCPY
904         sub     $16, %r8
905         jbe     LABEL(strncpy_truncation_unaligned)
906 #endif
908         palignr $4, (%rsi, %rcx), %xmm3
909         movdqa  %xmm3, (%rdi, %rcx)
910         add     $16, %rcx
912 #ifdef USE_AS_STRNCPY
913         cmp     %r10, %r8
914         jbe     LABEL(unaligned_exit)
915 #endif
916         jmp     LABEL(ashr_4_use_ssse3)
920  * The following cases will be handled by ashr_3
921  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
922  *      n(3~15)         n - 3           3((16 - (n -3) + n)%16   ashr_3
924  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
925  */
926         .p2align 4
927 LABEL(ashr_3):
928         xor     %ecx, %ecx                              /*clear ecx */
929 #ifdef USE_AS_STRNCPY
930         cmp     %r10, %r8
931         jbe     LABEL(unaligned_exit)
932 #endif
934         .p2align 4
935 LABEL(ashr_3_use_ssse3):
936         movdqa  16(%rsi, %rcx), %xmm3
937         pcmpeqb %xmm3, %xmm0
938         pmovmskb %xmm0, %edx
939         test    %edx, %edx
940         jnz     LABEL(unaligned_exit)
941 #ifdef USE_AS_STRNCPY
942         sub     $16, %r8
943         jbe     LABEL(strncpy_truncation_unaligned)
944 #endif
946         palignr $3, (%rsi, %rcx), %xmm3
947         movdqa  %xmm3, (%rdi, %rcx)
948         add     $16, %rcx
950 #ifdef USE_AS_STRNCPY
951         cmp     %r10, %r8
952         jbe     LABEL(unaligned_exit)
953 #endif
955         movdqa  16(%rsi, %rcx), %xmm3
956         pcmpeqb %xmm3, %xmm0
957         pmovmskb %xmm0, %edx
958         test    %edx, %edx
959         jnz     LABEL(unaligned_exit)
960 #ifdef USE_AS_STRNCPY
961         sub     $16, %r8
962         jbe     LABEL(strncpy_truncation_unaligned)
963 #endif
965         palignr $3, (%rsi, %rcx), %xmm3
966         movdqa  %xmm3, (%rdi, %rcx)
967         add     $16, %rcx
969 #ifdef USE_AS_STRNCPY
970         cmp     %r10, %r8
971         jbe     LABEL(unaligned_exit)
972 #endif
973         jmp     LABEL(ashr_3_use_ssse3)
977  * The following cases will be handled by ashr_2
978  *  rcx(offset of rsi)  rax(offset of rdi)      relative offset           corresponding case
979  *      n(2~15)         n - 2           2((16 - (n -2) + n)%16   ashr_2
981  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
982  */
983         .p2align 4
984 LABEL(ashr_2):
985         xor     %ecx, %ecx                              /*clear ecx */
986 #ifdef USE_AS_STRNCPY
987         cmp     %r10, %r8
988         jbe     LABEL(unaligned_exit)
989 #endif
991         .p2align 4
992 LABEL(ashr_2_use_ssse3):
993         movdqa  16(%rsi, %rcx), %xmm3
994         pcmpeqb %xmm3, %xmm0
995         pmovmskb %xmm0, %edx
996         test    %edx, %edx
997         jnz     LABEL(unaligned_exit)
998 #ifdef USE_AS_STRNCPY
999         sub     $16, %r8
1000         jbe     LABEL(strncpy_truncation_unaligned)
1001 #endif
1003         palignr $2, (%rsi, %rcx), %xmm3
1004         movdqa  %xmm3, (%rdi, %rcx)
1005         add     $16, %rcx
1007 #ifdef USE_AS_STRNCPY
1008         cmp     %r10, %r8
1009         jbe     LABEL(unaligned_exit)
1010 #endif
1012         movdqa  16(%rsi, %rcx), %xmm3
1013         pcmpeqb %xmm3, %xmm0
1014         pmovmskb %xmm0, %edx
1015         test    %edx, %edx
1016         jnz     LABEL(unaligned_exit)
1017 #ifdef USE_AS_STRNCPY
1018         sub     $16, %r8
1019         jbe     LABEL(strncpy_truncation_unaligned)
1020 #endif
1022         palignr $2, (%rsi, %rcx), %xmm3
1023         movdqa  %xmm3, (%rdi, %rcx)
1024         add     $16, %rcx
1026 #ifdef USE_AS_STRNCPY
1027         cmp     %r10, %r8
1028         jbe     LABEL(unaligned_exit)
1029 #endif
1030         jmp     LABEL(ashr_2_use_ssse3)
1034  * The following cases will be handled by ashr_1
1035  *  rcx(offset of rsi)  rax(offset of rdi)  relative offset             corresponding case
1036  *      n(1~15)         n - 1           1 ((16 - (n -1) + n)%16  ashr_1
1038  * Based on above operation , start from  (%r9 + rsi) to the left of this cache bank, there is no null byte
1039  */
1040         .p2align 4
1041 LABEL(ashr_1):
1042         xor     %ecx, %ecx                              /*clear ecx */
1043 #ifdef USE_AS_STRNCPY
1044         cmp     %r10, %r8
1045         jbe     LABEL(unaligned_exit)
1046 #endif
1048         .p2align 4
1049 LABEL(ashr_1_use_ssse3):
1050         movdqa  16(%rsi, %rcx), %xmm3
1051         pcmpeqb %xmm3, %xmm0
1052         pmovmskb %xmm0, %edx
1053         test    %edx, %edx
1054         jnz     LABEL(unaligned_exit)
1055 #ifdef USE_AS_STRNCPY
1056         sub     $16, %r8
1057         jbe     LABEL(strncpy_truncation_unaligned)
1058 #endif
1060         palignr $1, (%rsi, %rcx), %xmm3
1061         movdqa  %xmm3, (%rdi, %rcx)
1062         add     $16, %rcx
1063 #ifdef USE_AS_STRNCPY
1064         cmp     %r10, %r8
1065         jbe     LABEL(unaligned_exit)
1066 #endif
1068         movdqa  16(%rsi, %rcx), %xmm3
1069         pcmpeqb %xmm3, %xmm0
1070         pmovmskb %xmm0, %edx
1071         test    %edx, %edx
1072         jnz     LABEL(unaligned_exit)
1073 #ifdef USE_AS_STRNCPY
1074         sub     $16, %r8
1075         jbe     LABEL(strncpy_truncation_unaligned)
1076 #endif
1077         palignr $1, (%rsi, %rcx), %xmm3
1078         movdqa  %xmm3, (%rdi, %rcx)
1079         add     $16, %rcx
1081 #ifdef USE_AS_STRNCPY
1082         cmp     %r10, %r8
1083         jbe     LABEL(unaligned_exit)
1084 #endif
1085         jmp     LABEL(ashr_1_use_ssse3)
1087         .p2align 4
1088 LABEL(less32bytes):
1089         xor     %ecx, %ecx
1090 LABEL(unaligned_exit):
1091         add     %r9, %rsi               /* r9 stores original offset of rsi*/
1092         mov     %rcx, %r9
1093         mov     %r10, %rcx
1094         shl     %cl, %edx               /* after shl, calculate the exact number to be filled*/
1095         mov     %r9, %rcx
1096         .p2align 4
1097 LABEL(aligned_exit):
1098         add     %rcx, %rdi              /*locate exact address for rdi */
1099 LABEL(less16bytes):
1100         add     %rcx, %rsi              /*locate exact address for rsi */
1101 LABEL(aligned_16bytes):
1102 #ifdef USE_AS_STRNCPY
1103         mov     $1, %r9d
1104         lea     -1(%r8), %rcx
1105         shl     %cl, %r9d
1106         cmp     $32, %r8
1107         ja      LABEL(strncpy_tail)
1108         or      %r9d, %edx
1109 LABEL(strncpy_tail):
1110 #endif
1111         bsf     %rdx, %rcx              /*If a least significant 1 bit in %rdx is found, its bit index is stored in %rcx*/
1112         lea     LABEL(tail_table)(%rip), %r11
1113         movslq  (%r11, %rcx,4), %rcx
1114         lea     (%r11, %rcx), %rcx
1115         jmp     *%rcx
1117 #ifdef USE_AS_STRNCPY
1118         .p2align 4
1119 LABEL(less32bytes_strncpy_truncation):
1120         xor     %ecx, %ecx
1121 LABEL(strncpy_truncation_unaligned):
1122         add      %r9, %rsi
1123 LABEL(strncpy_truncation_aligned):
1124         add      %rcx, %rdi
1125         add      %rcx, %rsi
1126         add     $16, %r8
1127         lea     -1(%r8), %rcx
1128         lea     LABEL(tail_table)(%rip), %r11
1129         movslq  (%r11, %rcx,4), %rcx
1130         lea     (%r11, %rcx), %rcx
1131         jmp     *%rcx
1132         .p2align 4
1133 LABEL(strncpy_exitz):
1134         mov     %rdi, %rax
1135         ret
1136 #endif
1138 #ifdef USE_AS_STRNCPY
1139         .p2align 4
1140 LABEL(strncpy_fill_tail):
1141         mov     %rax, %rdx
1142         movzx   %cl, %rax
1143         mov     %r8, %rcx
1144         add     %rax, %rdi
1145         xor     %eax, %eax
1146         shr     $3, %ecx
1147         jz      LABEL(strncpy_fill_less_8)
1149         rep     stosq
1150 LABEL(strncpy_fill_less_8):
1151         mov     %r8, %rcx
1152         and     $7, %ecx
1153         jz      LABEL(strncpy_fill_return)
1154 LABEL(strncpy_fill_less_7):
1155         sub     $1, %ecx
1156         mov     %al, (%rdi, %rcx)
1157         jnz     LABEL(strncpy_fill_less_7)
1158 LABEL(strncpy_fill_return):
1159 #ifdef USE_AS_STPCPY
1160         cmpb    $1, (%rdx)
1161         sbb     $-1, %rdx
1162 #endif
1163         mov     %rdx, %rax
1164         ret
1165 #endif
1166         .p2align 4
1167 LABEL(tail_0):
1168         mov     (%rsi), %cl
1169         mov     %cl, (%rdi)
1170 #ifdef USE_AS_STPCPY
1171         mov     %rdi, %rax
1172 #endif
1173 #ifdef USE_AS_STRNCPY
1174         mov     $1, %cl
1175         sub     $1, %r8
1176         jnz     LABEL(strncpy_fill_tail)
1177 #ifdef USE_AS_STPCPY
1178         cmpb    $1, (%rax)
1179         sbb     $-1, %rax
1180 #endif
1181 #endif
1182         ret
1183         .p2align 4
1184 LABEL(tail_1):
1185         mov     (%rsi), %cx
1186         mov     %cx, (%rdi)
1187 #ifdef USE_AS_STPCPY
1188         lea     1(%rdi), %rax
1189 #endif
1190 #ifdef USE_AS_STRNCPY
1191         mov     $2, %cl
1192         sub     $2, %r8
1193         jnz     LABEL(strncpy_fill_tail)
1194 #ifdef USE_AS_STPCPY
1195         cmpb    $1, (%rax)
1196         sbb     $-1, %rax
1197 #endif
1198 #endif
1199         ret
1200         .p2align 4
1201 LABEL(tail_2):
1202         mov     (%rsi), %cx
1203         mov     %cx, (%rdi)
1204         mov     1(%rsi), %cx
1205         mov     %cx, 1(%rdi)
1206 #ifdef USE_AS_STPCPY
1207         lea     2(%rdi), %rax
1208 #endif
1209 #ifdef USE_AS_STRNCPY
1210         mov     $3, %cl
1211         sub     $3, %r8
1212         jnz     LABEL(strncpy_fill_tail)
1213 #ifdef USE_AS_STPCPY
1214         cmpb    $1, (%rax)
1215         sbb     $-1, %rax
1216 #endif
1217 #endif
1218         ret
1219         .p2align 4
1220 LABEL(tail_3):
1221         mov     (%rsi), %ecx
1222         mov     %ecx, (%rdi)
1223 #ifdef USE_AS_STPCPY
1224         lea     3(%rdi), %rax
1225 #endif
1226 #ifdef USE_AS_STRNCPY
1227         mov     $4, %cl
1228         sub     $4, %r8
1229         jnz     LABEL(strncpy_fill_tail)
1230 #ifdef USE_AS_STPCPY
1231         cmpb    $1, (%rax)
1232         sbb     $-1, %rax
1233 #endif
1234 #endif
1235         ret
1236         .p2align 4
1237 LABEL(tail_4):
1238         mov     (%rsi), %ecx
1239         mov     %ecx, (%rdi)
1240         mov     1(%rsi), %edx
1241         mov     %edx, 1(%rdi)
1242 #ifdef USE_AS_STPCPY
1243         lea     4(%rdi), %rax
1244 #endif
1245 #ifdef USE_AS_STRNCPY
1246         mov     $5, %cl
1247         sub     $5, %r8
1248         jnz     LABEL(strncpy_fill_tail)
1249 #ifdef USE_AS_STPCPY
1250         cmpb    $1, (%rax)
1251         sbb     $-1, %rax
1252 #endif
1253 #endif
1254         ret
1255         .p2align 4
1256 LABEL(tail_5):
1257         mov     (%rsi), %ecx
1258         mov     %ecx, (%rdi)
1259         mov     2(%rsi), %edx
1260         mov     %edx, 2(%rdi)
1261 #ifdef USE_AS_STPCPY
1262         lea     5(%rdi), %rax
1263 #endif
1264 #ifdef USE_AS_STRNCPY
1265         mov     $6, %cl
1266         sub     $6, %r8
1267         jnz     LABEL(strncpy_fill_tail)
1268 #ifdef USE_AS_STPCPY
1269         cmpb    $1, (%rax)
1270         sbb     $-1, %rax
1271 #endif
1272 #endif
1273         ret
1274         .p2align 4
1275 LABEL(tail_6):
1276         mov     (%rsi), %ecx
1277         mov     %ecx, (%rdi)
1278         mov     3(%rsi), %edx
1279         mov     %edx,3(%rdi)
1280 #ifdef USE_AS_STPCPY
1281         lea     6(%rdi), %rax
1282 #endif
1283 #ifdef USE_AS_STRNCPY
1284         mov     $7, %cl
1285         sub     $7, %r8
1286         jnz     LABEL(strncpy_fill_tail)
1287 #ifdef USE_AS_STPCPY
1288         cmpb    $1, (%rax)
1289         sbb     $-1, %rax
1290 #endif
1291 #endif
1292         ret
1294         .p2align 4
1295 LABEL(tail_7):
1296         mov     (%rsi), %rcx
1297         mov     %rcx, (%rdi)
1298 #ifdef USE_AS_STPCPY
1299         lea     7(%rdi), %rax
1300 #endif
1301 #ifdef USE_AS_STRNCPY
1302         mov     $8, %cl
1303         sub     $8, %r8
1304         jnz     LABEL(strncpy_fill_tail)
1305 #ifdef USE_AS_STPCPY
1306         cmpb    $1, (%rax)
1307         sbb     $-1, %rax
1308 #endif
1309 #endif
1310         ret
1312         .p2align 4
1313 LABEL(tail_8):
1315         mov     (%rsi), %rcx
1316         mov     %rcx, (%rdi)
1317         mov     5(%rsi), %edx
1318         mov     %edx, 5(%rdi)
1319 #ifdef USE_AS_STPCPY
1320         lea     8(%rdi), %rax
1321 #endif
1322 #ifdef USE_AS_STRNCPY
1323         mov     $9, %cl
1324         sub     $9, %r8
1325         jnz     LABEL(strncpy_fill_tail)
1326 #ifdef USE_AS_STPCPY
1327         cmpb    $1, (%rax)
1328         sbb     $-1, %rax
1329 #endif
1330 #endif
1331         ret
1333         .p2align 4
1334 LABEL(tail_9):
1335         mov     (%rsi), %rcx
1336         mov     %rcx, (%rdi)
1337         mov     6(%rsi), %edx
1338         mov     %edx, 6(%rdi)
1339 #ifdef USE_AS_STPCPY
1340         lea     9(%rdi), %rax
1341 #endif
1342 #ifdef USE_AS_STRNCPY
1343         mov     $10, %cl
1344         sub     $10, %r8
1345         jnz     LABEL(strncpy_fill_tail)
1346 #ifdef USE_AS_STPCPY
1347         cmpb    $1, (%rax)
1348         sbb     $-1, %rax
1349 #endif
1350 #endif
1351         ret
1353         .p2align 4
1354 LABEL(tail_10):
1355         mov     (%rsi), %rcx
1356         mov     %rcx, (%rdi)
1357         mov     7(%rsi), %edx
1358         mov     %edx, 7(%rdi)
1359 #ifdef USE_AS_STPCPY
1360         lea     10(%rdi), %rax
1361 #endif
1362 #ifdef USE_AS_STRNCPY
1363         mov     $11, %cl
1364         sub     $11, %r8
1365         jnz     LABEL(strncpy_fill_tail)
1366 #ifdef USE_AS_STPCPY
1367         cmpb    $1, (%rax)
1368         sbb     $-1, %rax
1369 #endif
1370 #endif
1371         ret
1372         .p2align 4
1373 LABEL(tail_11):
1374         mov     (%rsi), %rcx
1375         mov     %rcx, (%rdi)
1376         mov     8(%rsi), %edx
1377         mov     %edx, 8(%rdi)
1378 #ifdef USE_AS_STPCPY
1379         lea     11(%rdi), %rax
1380 #endif
1381 #ifdef USE_AS_STRNCPY
1382         mov     $12, %cl
1383         sub     $12, %r8
1384         jnz     LABEL(strncpy_fill_tail)
1385 #ifdef USE_AS_STPCPY
1386         cmpb    $1, (%rax)
1387         sbb     $-1, %rax
1388 #endif
1389 #endif
1390         ret
1391         .p2align 4
1392 LABEL(tail_12):
1393         mov     (%rsi), %rcx
1394         mov     %rcx, (%rdi)
1395         mov     5(%rsi), %rcx
1396         mov     %rcx, 5(%rdi)
1397 #ifdef USE_AS_STPCPY
1398         lea     12(%rdi), %rax
1399 #endif
1400 #ifdef USE_AS_STRNCPY
1401         mov     $13, %cl
1402         sub     $13, %r8
1403         jnz     LABEL(strncpy_fill_tail)
1404 #ifdef USE_AS_STPCPY
1405         cmpb    $1, (%rax)
1406         sbb     $-1, %rax
1407 #endif
1408 #endif
1409         ret
1411         .p2align 4
1412 LABEL(tail_13):
1413         mov     (%rsi), %rcx
1414         mov     %rcx, (%rdi)
1415         mov     6(%rsi), %rcx
1416         mov     %rcx, 6(%rdi)
1417 #ifdef USE_AS_STPCPY
1418         lea     13(%rdi), %rax
1419 #endif
1420 #ifdef USE_AS_STRNCPY
1421         mov     $14, %cl
1422         sub     $14, %r8
1423         jnz     LABEL(strncpy_fill_tail)
1424 #ifdef USE_AS_STPCPY
1425         cmpb    $1, (%rax)
1426         sbb     $-1, %rax
1427 #endif
1428 #endif
1429         ret
1431         .p2align 4
1432 LABEL(tail_14):
1433         mov     (%rsi), %rcx
1434         mov     %rcx, (%rdi)
1435         mov     7(%rsi), %rcx
1436         mov     %rcx, 7(%rdi)
1437 #ifdef USE_AS_STPCPY
1438         lea     14(%rdi), %rax
1439 #endif
1440 #ifdef USE_AS_STRNCPY
1441         mov     $15, %cl
1442         sub     $15, %r8
1443         jnz     LABEL(strncpy_fill_tail)
1444 #ifdef USE_AS_STPCPY
1445         cmpb    $1, (%rax)
1446         sbb     $-1, %rax
1447 #endif
1448 #endif
1449         ret
1451 LABEL(tail_15):
1452         mov     (%rsi), %rcx
1453         mov     %rcx, (%rdi)
1454         mov     8(%rsi), %rdx
1455         mov     %rdx, 8(%rdi)
1456 #ifdef USE_AS_STPCPY
1457         lea     15(%rdi), %rax
1458 #endif
1459 #ifdef USE_AS_STRNCPY
1460         mov     $16, %cl
1461         sub     $16, %r8
1462         jnz     LABEL(strncpy_fill_tail)
1463 #ifdef USE_AS_STPCPY
1464         cmpb    $1, (%rax)
1465         sbb     $-1, %rax
1466 #endif
1467 #endif
1469         ret
1471         .p2align 4
1472 LABEL(tail_16):
1473         mov     (%rsi), %rcx
1474         mov     %rcx, (%rdi)
1475         mov     8(%rsi), %rdx
1476         mov     %rdx, 8(%rdi)
1477         mov     16(%rsi), %cl
1478         mov     %cl, 16(%rdi)
1479 #ifdef USE_AS_STPCPY
1480         lea     16(%rdi), %rax
1481 #endif
1482 #ifdef USE_AS_STRNCPY
1483         mov     $17, %cl
1484         sub     $17, %r8
1485         jnz     LABEL(strncpy_fill_tail)
1486 #ifdef USE_AS_STPCPY
1487         cmpb    $1, (%rax)
1488         sbb     $-1, %rax
1489 #endif
1490 #endif
1491         ret
1492         .p2align 4
1493 LABEL(tail_17):
1494         mov     (%rsi), %rcx
1495         mov     %rcx, (%rdi)
1496         mov     8(%rsi), %rdx
1497         mov     %rdx, 8(%rdi)
1498         mov     16(%rsi), %cx
1499         mov     %cx, 16(%rdi)
1500 #ifdef USE_AS_STPCPY
1501         lea     17(%rdi), %rax
1502 #endif
1503 #ifdef USE_AS_STRNCPY
1504         mov     $18, %cl
1505         sub     $18, %r8
1506         jnz     LABEL(strncpy_fill_tail)
1507 #ifdef USE_AS_STPCPY
1508         cmpb    $1, (%rax)
1509         sbb     $-1, %rax
1510 #endif
1511 #endif
1512         ret
1514         .p2align 4
1515 LABEL(tail_18):
1516         mov     (%rsi), %rcx
1517         mov     %rcx, (%rdi)
1518         mov     8(%rsi), %rdx
1519         mov     %rdx, 8(%rdi)
1520         mov     15(%rsi), %ecx
1521         mov     %ecx,15(%rdi)
1522 #ifdef USE_AS_STPCPY
1523         lea     18(%rdi), %rax
1524 #endif
1525 #ifdef USE_AS_STRNCPY
1526         mov     $19, %cl
1527         sub     $19, %r8
1528         jnz     LABEL(strncpy_fill_tail)
1529 #ifdef USE_AS_STPCPY
1530         cmpb    $1, (%rax)
1531         sbb     $-1, %rax
1532 #endif
1533 #endif
1534         ret
1536         .p2align 4
1537 LABEL(tail_19):
1538         mov     (%rsi), %rcx
1539         mov     %rcx, (%rdi)
1540         mov     8(%rsi), %rdx
1541         mov     %rdx, 8(%rdi)
1542         mov     16(%rsi), %ecx
1543         mov     %ecx, 16(%rdi)
1544 #ifdef USE_AS_STPCPY
1545         lea     19(%rdi), %rax
1546 #endif
1547 #ifdef USE_AS_STRNCPY
1548         mov     $20, %cl
1549         sub     $20, %r8
1550         jnz     LABEL(strncpy_fill_tail)
1551 #ifdef USE_AS_STPCPY
1552         cmpb    $1, (%rax)
1553         sbb     $-1, %rax
1554 #endif
1555 #endif
1556         ret
1557         .p2align 4
1558 LABEL(tail_20):
1559         mov     (%rsi), %rcx
1560         mov     %rcx, (%rdi)
1561         mov     8(%rsi), %rdx
1562         mov     %rdx, 8(%rdi)
1563         mov     13(%rsi), %rcx
1564         mov     %rcx, 13(%rdi)
1565 #ifdef USE_AS_STPCPY
1566         lea     20(%rdi), %rax
1567 #endif
1568 #ifdef USE_AS_STRNCPY
1569         mov     $21, %cl
1570         sub     $21, %r8
1571         jnz     LABEL(strncpy_fill_tail)
1572 #ifdef USE_AS_STPCPY
1573         cmpb    $1, (%rax)
1574         sbb     $-1, %rax
1575 #endif
1576 #endif
1577         ret
1578         .p2align 4
1579 LABEL(tail_21):
1580         mov     (%rsi), %rcx
1581         mov     %rcx, (%rdi)
1582         mov     8(%rsi), %rdx
1583         mov     %rdx, 8(%rdi)
1584         mov     14(%rsi), %rcx
1585         mov     %rcx, 14(%rdi)
1586 #ifdef USE_AS_STPCPY
1587         lea     21(%rdi), %rax
1588 #endif
1589 #ifdef USE_AS_STRNCPY
1590         mov     $22, %cl
1591         sub     $22, %r8
1592         jnz     LABEL(strncpy_fill_tail)
1593 #ifdef USE_AS_STPCPY
1594         cmpb    $1, (%rax)
1595         sbb     $-1, %rax
1596 #endif
1597 #endif
1598         ret
1600         .p2align 4
1601 LABEL(tail_22):
1602         mov     (%rsi), %rcx
1603         mov     %rcx, (%rdi)
1604         mov     8(%rsi), %rdx
1605         mov     %rdx, 8(%rdi)
1606         mov     15(%rsi), %rcx
1607         mov     %rcx, 15(%rdi)
1608 #ifdef USE_AS_STPCPY
1609         lea     22(%rdi), %rax
1610 #endif
1611 #ifdef USE_AS_STRNCPY
1612         mov     $23, %cl
1613         sub     $23, %r8
1614         jnz     LABEL(strncpy_fill_tail)
1615 #ifdef USE_AS_STPCPY
1616         cmpb    $1, (%rax)
1617         sbb     $-1, %rax
1618 #endif
1619 #endif
1620         ret
1622         .p2align 4
1623 LABEL(tail_23):
1624         mov     (%rsi), %rcx
1625         mov     %rcx, (%rdi)
1626         mov     8(%rsi), %rdx
1627         mov     %rdx, 8(%rdi)
1628         mov     16(%rsi), %rcx
1629         mov     %rcx, 16(%rdi)
1630 #ifdef USE_AS_STPCPY
1631         lea     23(%rdi), %rax
1632 #endif
1633 #ifdef USE_AS_STRNCPY
1634         mov     $24, %cl
1635         sub     $24, %r8
1636         jnz     LABEL(strncpy_fill_tail)
1637 #ifdef USE_AS_STPCPY
1638         cmpb    $1, (%rax)
1639         sbb     $-1, %rax
1640 #endif
1641 #endif
1643         ret
1645         .p2align 4
1646 LABEL(tail_24):
1647         mov     (%rsi), %rcx
1648         mov     %rcx, (%rdi)
1649         mov     8(%rsi), %rdx
1650         mov     %rdx, 8(%rdi)
1651         mov     16(%rsi), %rcx
1652         mov     %rcx, 16(%rdi)
1653         mov     21(%rsi), %edx
1654         mov     %edx, 21(%rdi)
1655 #ifdef USE_AS_STPCPY
1656         lea     24(%rdi), %rax
1657 #endif
1658 #ifdef USE_AS_STRNCPY
1659         mov     $25, %cl
1660         sub     $25, %r8
1661         jnz     LABEL(strncpy_fill_tail)
1662 #ifdef USE_AS_STPCPY
1663         cmpb    $1, (%rax)
1664         sbb     $-1, %rax
1665 #endif
1666 #endif
1667         ret
1669         .p2align 4
1670 LABEL(tail_25):
1671         mov     (%rsi), %rcx
1672         mov     %rcx, (%rdi)
1673         mov     8(%rsi), %rdx
1674         mov     %rdx, 8(%rdi)
1675         mov     16(%rsi), %rcx
1676         mov     %rcx, 16(%rdi)
1677         mov     22(%rsi), %edx
1678         mov     %edx, 22(%rdi)
1679 #ifdef USE_AS_STPCPY
1680         lea     25(%rdi), %rax
1681 #endif
1682 #ifdef USE_AS_STRNCPY
1683         mov     $26, %cl
1684         sub     $26, %r8
1685         jnz     LABEL(strncpy_fill_tail)
1686 #ifdef USE_AS_STPCPY
1687         cmpb    $1, (%rax)
1688         sbb     $-1, %rax
1689 #endif
1690 #endif
1691         ret
1693         .p2align 4
1694 LABEL(tail_26):
1695         mov     (%rsi), %rcx
1696         mov     %rcx, (%rdi)
1697         mov     8(%rsi), %rdx
1698         mov     %rdx, 8(%rdi)
1699         mov     16(%rsi), %rcx
1700         mov     %rcx, 16(%rdi)
1701         mov     23(%rsi), %edx
1702         mov     %edx, 23(%rdi)
1703 #ifdef USE_AS_STPCPY
1704         lea     26(%rdi), %rax
1705 #endif
1706 #ifdef USE_AS_STRNCPY
1707         mov     $27, %cl
1708         sub     $27, %r8
1709         jnz     LABEL(strncpy_fill_tail)
1710 #ifdef USE_AS_STPCPY
1711         cmpb    $1, (%rax)
1712         sbb     $-1, %rax
1713 #endif
1714 #endif
1715         ret
1717         .p2align 4
1718 LABEL(tail_27):
1719         mov     (%rsi), %rcx
1720         mov     %rcx, (%rdi)
1721         mov     8(%rsi), %rdx
1722         mov     %rdx, 8(%rdi)
1723         mov     16(%rsi), %rcx
1724         mov     %rcx, 16(%rdi)
1725         mov     24(%rsi), %edx
1726         mov     %edx, 24(%rdi)
1727 #ifdef USE_AS_STPCPY
1728         lea     27(%rdi), %rax
1729 #endif
1730 #ifdef USE_AS_STRNCPY
1731         mov     $28, %cl
1732         sub     $28, %r8
1733         jnz     LABEL(strncpy_fill_tail)
1734 #ifdef USE_AS_STPCPY
1735         cmpb    $1, (%rax)
1736         sbb     $-1, %rax
1737 #endif
1738 #endif
1739         ret
1740         .p2align 4
1741 LABEL(tail_28):
1742         mov     (%rsi), %rcx
1743         mov     %rcx, (%rdi)
1744         mov     8(%rsi), %rdx
1745         mov     %rdx, 8(%rdi)
1746         mov     16(%rsi), %rcx
1747         mov     %rcx, 16(%rdi)
1748         mov     21(%rsi), %rdx
1749         mov     %rdx, 21(%rdi)
1750 #ifdef USE_AS_STPCPY
1751         lea     28(%rdi), %rax
1752 #endif
1753 #ifdef USE_AS_STRNCPY
1754         mov     $29, %cl
1755         sub     $29, %r8
1756         jnz     LABEL(strncpy_fill_tail)
1757 #ifdef USE_AS_STPCPY
1758         cmpb    $1, (%rax)
1759         sbb     $-1, %rax
1760 #endif
1761 #endif
1763         ret
1765         .p2align 4
1766 LABEL(tail_29):
1767         mov     (%rsi), %rcx
1768         mov     %rcx, (%rdi)
1769         mov     8(%rsi), %rdx
1770         mov     %rdx, 8(%rdi)
1771         mov     16(%rsi), %rcx
1772         mov     %rcx, 16(%rdi)
1773         mov     22(%rsi), %rdx
1774         mov     %rdx, 22(%rdi)
1775 #ifdef USE_AS_STPCPY
1776         lea     29(%rdi), %rax
1777 #endif
1778 #ifdef USE_AS_STRNCPY
1779         mov     $30, %cl
1780         sub     $30, %r8
1781         jnz     LABEL(strncpy_fill_tail)
1782 #ifdef USE_AS_STPCPY
1783         cmpb    $1, (%rax)
1784         sbb     $-1, %rax
1785 #endif
1786 #endif
1788         ret
1791         .p2align 4
1792 LABEL(tail_30):
1793         mov     (%rsi), %rcx
1794         mov     %rcx, (%rdi)
1795         mov     8(%rsi), %rdx
1796         mov     %rdx, 8(%rdi)
1797         mov     16(%rsi), %rcx
1798         mov     %rcx, 16(%rdi)
1799         mov     23(%rsi), %rdx
1800         mov     %rdx, 23(%rdi)
1801 #ifdef USE_AS_STPCPY
1802         lea     30(%rdi), %rax
1803 #endif
1804 #ifdef USE_AS_STRNCPY
1805         mov     $31, %cl
1806         sub     $31, %r8
1807         jnz     LABEL(strncpy_fill_tail)
1808 #ifdef USE_AS_STPCPY
1809         cmpb    $1, (%rax)
1810         sbb     $-1, %rax
1811 #endif
1812 #endif
1813         ret
1815         .p2align 4
1816 LABEL(tail_31):
1817         mov     (%rsi), %rcx
1818         mov     %rcx, (%rdi)
1819         mov     8(%rsi), %rdx
1820         mov     %rdx, 8(%rdi)
1821         mov     16(%rsi), %rcx
1822         mov     %rcx, 16(%rdi)
1823         mov     24(%rsi), %rdx
1824         mov     %rdx, 24(%rdi)
1825 #ifdef USE_AS_STPCPY
1826         lea     31(%rdi), %rax
1827 #endif
1828 #ifdef USE_AS_STRNCPY
1829         mov     $32, %cl
1830         sub     $32, %r8
1831         jnz     LABEL(strncpy_fill_tail)
1832 #ifdef USE_AS_STPCPY
1833         cmpb    $1, (%rax)
1834         sbb     $-1, %rax
1835 #endif
1836 #endif
1837         ret
1838         cfi_endproc
1839         .size   STRCPY_SSSE3, .-STRCPY_SSSE3
1841         .p2align 4
1842         .section .rodata.ssse3,"a",@progbits
1843 LABEL(tail_table):
1844         .int    LABEL(tail_0) - LABEL(tail_table)
1845         .int    LABEL(tail_1) - LABEL(tail_table)
1846         .int    LABEL(tail_2) - LABEL(tail_table)
1847         .int    LABEL(tail_3) - LABEL(tail_table)
1848         .int    LABEL(tail_4) - LABEL(tail_table)
1849         .int    LABEL(tail_5) - LABEL(tail_table)
1850         .int    LABEL(tail_6) - LABEL(tail_table)
1851         .int    LABEL(tail_7) - LABEL(tail_table)
1852         .int    LABEL(tail_8) - LABEL(tail_table)
1853         .int    LABEL(tail_9) - LABEL(tail_table)
1854         .int    LABEL(tail_10) - LABEL(tail_table)
1855         .int    LABEL(tail_11) - LABEL(tail_table)
1856         .int    LABEL(tail_12) - LABEL(tail_table)
1857         .int    LABEL(tail_13) - LABEL(tail_table)
1858         .int    LABEL(tail_14) - LABEL(tail_table)
1859         .int    LABEL(tail_15) - LABEL(tail_table)
1860         .int    LABEL(tail_16) - LABEL(tail_table)
1861         .int    LABEL(tail_17) - LABEL(tail_table)
1862         .int    LABEL(tail_18) - LABEL(tail_table)
1863         .int    LABEL(tail_19) - LABEL(tail_table)
1864         .int    LABEL(tail_20) - LABEL(tail_table)
1865         .int    LABEL(tail_21) - LABEL(tail_table)
1866         .int    LABEL(tail_22) - LABEL(tail_table)
1867         .int    LABEL(tail_23) - LABEL(tail_table)
1868         .int    LABEL(tail_24) - LABEL(tail_table)
1869         .int    LABEL(tail_25) - LABEL(tail_table)
1870         .int    LABEL(tail_26) - LABEL(tail_table)
1871         .int    LABEL(tail_27) - LABEL(tail_table)
1872         .int    LABEL(tail_28) - LABEL(tail_table)
1873         .int    LABEL(tail_29) - LABEL(tail_table)
1874         .int    LABEL(tail_30) - LABEL(tail_table)
1875         .int    LABEL(tail_31) - LABEL(tail_table)
1877         .p2align 4
1878 LABEL(unaligned_table):
1879         .int    LABEL(ashr_0) - LABEL(unaligned_table)
1880         .int    LABEL(ashr_1) - LABEL(unaligned_table)
1881         .int    LABEL(ashr_2) - LABEL(unaligned_table)
1882         .int    LABEL(ashr_3) - LABEL(unaligned_table)
1883         .int    LABEL(ashr_4) - LABEL(unaligned_table)
1884         .int    LABEL(ashr_5) - LABEL(unaligned_table)
1885         .int    LABEL(ashr_6) - LABEL(unaligned_table)
1886         .int    LABEL(ashr_7) - LABEL(unaligned_table)
1887         .int    LABEL(ashr_8) - LABEL(unaligned_table)
1888         .int    LABEL(ashr_9) - LABEL(unaligned_table)
1889         .int    LABEL(ashr_10) - LABEL(unaligned_table)
1890         .int    LABEL(ashr_11) - LABEL(unaligned_table)
1891         .int    LABEL(ashr_12) - LABEL(unaligned_table)
1892         .int    LABEL(ashr_13) - LABEL(unaligned_table)
1893         .int    LABEL(ashr_14) - LABEL(unaligned_table)
1894         .int    LABEL(ashr_15) - LABEL(unaligned_table)
1896 # undef ENTRY
1897 # define ENTRY(name) \
1898         .type STRCPY_SSE2, @function; \
1899         STRCPY_SSE2: cfi_startproc; \
1900         CALL_MCOUNT
1901 # undef END
1902 # define END(name) \
1903         cfi_endproc; .size STRCPY_SSE2, .-STRCPY_SSE2
1904 # undef libc_hidden_builtin_def
1905 /* It doesn't make sense to send libc-internal strcpy calls through a PLT.
1906    The speedup we get from using SSSE3 instruction is likely eaten away
1907    by the indirect call in the PLT.  */
1908 # define libc_hidden_builtin_def(name) \
1909         .globl __GI_STRCPY; __GI_STRCPY = STRCPY_SSE2
1910 # undef libc_hidden_def
1911 # define libc_hidden_def(name) \
1912         .globl __GI___STRCPY; __GI___STRCPY = STRCPY_SSE2
1913 #endif
1915 #ifndef USE_AS_STRNCPY
1916 #include "../strcpy.S"
1917 #endif