1 | /* strcpy/stpcpy implementation for i586. |
2 | Copyright (C) 1997-2024 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #include <sysdep.h> |
20 | #include "asm-syntax.h" |
21 | |
22 | #define PARMS 4+12 /* space for 3 saved regs */ |
23 | #define RTN PARMS |
24 | #define DEST RTN |
25 | #define SRC DEST+4 |
26 | |
27 | #ifndef USE_AS_STPCPY |
28 | # define STRCPY strcpy |
29 | #endif |
30 | |
31 | #define magic 0xfefefeff |
32 | |
33 | .text |
34 | ENTRY (STRCPY) |
35 | |
36 | pushl %edi |
37 | cfi_adjust_cfa_offset (4) |
38 | pushl %esi |
39 | cfi_adjust_cfa_offset (4) |
40 | pushl %ebx |
41 | cfi_adjust_cfa_offset (4) |
42 | |
43 | movl DEST(%esp), %edi |
44 | cfi_rel_offset (edi, 8) |
45 | movl SRC(%esp), %esi |
46 | cfi_rel_offset (esi, 4) |
47 | |
48 | xorl %eax, %eax |
49 | leal -1(%esi), %ecx |
50 | |
51 | movl $magic, %ebx |
52 | cfi_rel_offset (ebx, 0) |
53 | andl $3, %ecx |
54 | |
55 | cmpb $2, %cl |
56 | je L(Src2) |
57 | ja L(Src3) |
58 | cmpb $1, %cl |
59 | je L(Src1) |
60 | |
61 | L(Src0): |
62 | orb (%esi), %al |
63 | jz L(end) |
64 | stosb |
65 | xorl %eax, %eax |
66 | incl %esi |
67 | |
68 | L(Src1): |
69 | orb (%esi), %al |
70 | jz L(end) |
71 | stosb |
72 | xorl %eax, %eax |
73 | incl %esi |
74 | |
75 | L(Src2): |
76 | orb (%esi), %al |
77 | jz L(end) |
78 | stosb |
79 | xorl %eax, %eax |
80 | incl %esi |
81 | |
82 | L(Src3): |
83 | movl (%esi), %ecx |
84 | leal 4(%esi),%esi |
85 | |
86 | subl %ecx, %eax |
87 | addl %ebx, %ecx |
88 | |
89 | decl %eax |
90 | jnc L(3) |
91 | |
92 | movl %ecx, %edx |
93 | xorl %ecx, %eax |
94 | |
95 | subl %ebx, %edx |
96 | andl $~magic, %eax |
97 | |
98 | jne L(4) |
99 | |
100 | movl %edx, (%edi) |
101 | leal 4(%edi),%edi |
102 | |
103 | jmp L(Src3) |
104 | |
105 | L(3): movl %ecx, %edx |
106 | |
107 | subl %ebx, %edx |
108 | |
109 | L(4): movb %dl, (%edi) |
110 | testb %dl, %dl |
111 | |
112 | movl %edx, %eax |
113 | jz L(end2) |
114 | |
115 | shrl $16, %eax |
116 | movb %dh, 1(%edi) |
117 | #ifdef USE_AS_STPCPY |
118 | addl $1, %edi |
119 | #endif |
120 | |
121 | cmpb $0, %dh |
122 | jz L(end2) |
123 | |
124 | #ifdef USE_AS_STPCPY |
125 | movb %al, 1(%edi) |
126 | addl $1, %edi |
127 | |
128 | cmpb $0, %al |
129 | jz L(end2) |
130 | |
131 | addl $1, %edi |
132 | #else |
133 | movb %al, 2(%edi) |
134 | testb %al, %al |
135 | |
136 | leal 3(%edi), %edi |
137 | jz L(end2) |
138 | #endif |
139 | |
140 | L(end): movb %ah, (%edi) |
141 | |
142 | L(end2): |
143 | #ifdef USE_AS_STPCPY |
144 | movl %edi, %eax |
145 | #else |
146 | movl DEST(%esp), %eax |
147 | #endif |
148 | popl %ebx |
149 | cfi_adjust_cfa_offset (-4) |
150 | cfi_restore (ebx) |
151 | popl %esi |
152 | cfi_adjust_cfa_offset (-4) |
153 | cfi_restore (esi) |
154 | popl %edi |
155 | cfi_adjust_cfa_offset (-4) |
156 | cfi_restore (edi) |
157 | |
158 | ret |
159 | END (STRCPY) |
160 | #ifndef USE_AS_STPCPY |
161 | libc_hidden_builtin_def (strcpy) |
162 | #endif |
163 | |