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