* sysdeps/unix/sysv/linux/dl-sysdep.h: Use __ASSEMBLER__ instead
[glibc.git] / sysdeps / i386 / i586 / strcpy.S
blob5426e59749594a08c3a295a2eda1800f887337fa
1 /* strcpy/stpcpy implementation for i586.
2    Copyright (C) 1997, 2000, 2003, 2005 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
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 "asm-syntax.h"
23 #include "bp-sym.h"
24 #include "bp-asm.h"
26 #define PARMS   LINKAGE+12      /* space for 3 saved regs */
27 #define RTN     PARMS
28 #define DEST    RTN+RTN_SIZE
29 #define SRC     DEST+PTR_SIZE
31 #ifndef USE_AS_STPCPY
32 # define STRCPY strcpy
33 #endif
35 #define magic 0xfefefeff
37         .text
38 ENTRY (BP_SYM (STRCPY))
39         ENTER
41         pushl   %edi
42         cfi_adjust_cfa_offset (4)
43         pushl   %esi
44         cfi_adjust_cfa_offset (4)
45         pushl   %ebx
46         cfi_adjust_cfa_offset (4)
48         movl    DEST(%esp), %edi
49         cfi_rel_offset (edi, 8)
50         movl    SRC(%esp), %esi
51         cfi_rel_offset (esi, 4)
52         CHECK_BOUNDS_LOW (%edi, DEST(%esp))
53         CHECK_BOUNDS_LOW (%esi, SRC(%esp))
55         xorl    %eax, %eax
56         leal    -1(%esi), %ecx
58         movl    $magic, %ebx
59         cfi_rel_offset (ebx, 0)
60         andl    $3, %ecx
62 #ifdef PIC
63         call    2f
64         cfi_adjust_cfa_offset (4)
65 2:      popl    %edx
66         cfi_adjust_cfa_offset (-4)
67         /* 0xb is the distance between 2: and 1: but we avoid writing
68            1f-2b because the assembler generates worse code.  */
69         leal    0xb(%edx,%ecx,8), %ecx
70 #else
71         leal    1f(,%ecx,8), %ecx
72 #endif
74         jmp     *%ecx
76         .align 8
78         orb     (%esi), %al
79         jz      L(end)
80         stosb
81         xorl    %eax, %eax
82         incl    %esi
84         orb     (%esi), %al
85         jz      L(end)
86         stosb
87         xorl    %eax, %eax
88         incl    %esi
90         orb     (%esi), %al
91         jz      L(end)
92         stosb
93         xorl    %eax, %eax
94         incl    %esi
96 L(1):   movl    (%esi), %ecx
97         leal    4(%esi),%esi
99         subl    %ecx, %eax
100         addl    %ebx, %ecx
102         decl    %eax
103         jnc     L(3)
105         movl    %ecx, %edx
106         xorl    %ecx, %eax
108         subl    %ebx, %edx
109         andl    $~magic, %eax
111         jne     L(4)
113         movl    %edx, (%edi)
114         leal    4(%edi),%edi
116         jmp     L(1)
118 L(3):   movl    %ecx, %edx
120         subl    %ebx, %edx
122 L(4):   movb    %dl, (%edi)
123         testb   %dl, %dl
125         movl    %edx, %eax
126         jz      L(end2)
128         shrl    $16, %eax
129         movb    %dh, 1(%edi)
130 #ifdef USE_AS_STPCPY
131         addl    $1, %edi
132 #endif
134         cmpb    $0, %dh
135         jz      L(end2)
137 #ifdef USE_AS_STPCPY
138         movb    %al, 1(%edi)
139         addl    $1, %edi
141         cmpb    $0, %al
142         jz      L(end2)
144         addl    $1, %edi
145 #else
146         movb    %al, 2(%edi)
147         testb   %al, %al
149         leal    3(%edi), %edi
150         jz      L(end2)
151 #endif
153 L(end): movb    %ah, (%edi)
155 L(end2):
156         /* GKM FIXME: check high bounds  */
157 #ifdef USE_AS_STPCPY
158         movl    %edi, %eax
159 #else
160         movl    DEST(%esp), %eax
161 #endif
162         RETURN_BOUNDED_POINTER (DEST(%esp))
163         popl    %ebx
164         cfi_adjust_cfa_offset (-4)
165         cfi_restore (ebx)
166         popl    %esi
167         cfi_adjust_cfa_offset (-4)
168         cfi_restore (esi)
169         popl    %edi
170         cfi_adjust_cfa_offset (-4)
171         cfi_restore (edi)
173         LEAVE
174         RET_PTR
175 END (BP_SYM (STRCPY))
176 #ifndef USE_AS_STPCPY
177 libc_hidden_builtin_def (strcpy)
178 #endif