]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - lib/libc/amd64/string/stpcpy.S
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / lib / libc / amd64 / string / stpcpy.S
1 /*
2  * Adapted by Guillaume Morin <guillaume@morinfr.org> from strcpy.S
3  * written by J.T. Conklin <jtc@acorntoolworks.com>
4  * Public domain.
5  */
6
7 #include <machine/asm.h>
8 __FBSDID("$FreeBSD$");
9
10 /*
11  * This stpcpy implementation copies a byte at a time until the
12  * source pointer is aligned to a word boundary, it then copies by
13  * words until it finds a word containing a zero byte, and finally
14  * copies by bytes until the end of the string is reached.
15  *
16  * While this may result in unaligned stores if the source and
17  * destination pointers are unaligned with respect to each other,
18  * it is still faster than either byte copies or the overhead of
19  * an implementation suitable for machines with strict alignment
20  * requirements.
21  */
22
23         .globl  stpcpy,__stpcpy
24 ENTRY(stpcpy)
25 __stpcpy:
26         movabsq $0x0101010101010101,%r8
27         movabsq $0x8080808080808080,%r9
28
29         /*
30          * Align source to a word boundary.
31          * Consider unrolling loop?
32          */
33 .Lalign:
34         testb   $7,%sil
35         je      .Lword_aligned
36         movb    (%rsi),%dl
37         incq    %rsi
38         movb    %dl,(%rdi)
39         incq    %rdi
40         testb   %dl,%dl
41         jne     .Lalign
42         movq    %rdi,%rax
43         dec     %rax
44         ret
45
46         .p2align 4
47 .Lloop:
48         movq    %rdx,(%rdi)
49         addq    $8,%rdi
50 .Lword_aligned:
51         movq    (%rsi),%rdx
52         movq    %rdx,%rcx
53         addq    $8,%rsi
54         subq    %r8,%rcx
55         testq   %r9,%rcx
56         je      .Lloop
57
58         /*
59          * In rare cases, the above loop may exit prematurely. We must
60          * return to the loop if none of the bytes in the word equal 0.
61          */
62
63         movb    %dl,(%rdi)
64         testb   %dl,%dl         /* 1st byte == 0? */
65         je      .Ldone
66         incq    %rdi
67
68         shrq    $8,%rdx
69         movb    %dl,(%rdi)
70         testb   %dl,%dl         /* 2nd byte == 0? */
71         je      .Ldone
72         incq    %rdi
73
74         shrq    $8,%rdx
75         movb    %dl,(%rdi)
76         testb   %dl,%dl         /* 3rd byte == 0? */
77         je      .Ldone
78         incq    %rdi
79
80         shrq    $8,%rdx
81         movb    %dl,(%rdi)
82         testb   %dl,%dl         /* 4th byte == 0? */
83         je      .Ldone
84         incq    %rdi
85
86         shrq    $8,%rdx
87         movb    %dl,(%rdi)
88         testb   %dl,%dl         /* 5th byte == 0? */
89         je      .Ldone
90         incq    %rdi
91
92         shrq    $8,%rdx
93         movb    %dl,(%rdi)
94         testb   %dl,%dl         /* 6th byte == 0? */
95         je      .Ldone
96         incq    %rdi
97
98         shrq    $8,%rdx
99         movb    %dl,(%rdi)
100         testb   %dl,%dl         /* 7th byte == 0? */
101         je      .Ldone
102         incq    %rdi
103
104         shrq    $8,%rdx
105         movb    %dl,(%rdi)
106         incq    %rdi
107         testb   %dl,%dl         /* 8th byte == 0? */
108         jne     .Lword_aligned
109         decq    %rdi
110
111 .Ldone:
112         movq    %rdi,%rax
113         ret
114 END(stpcpy)
115         
116         .section .note.GNU-stack,"",%progbits