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