Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / i386 / i686 / multiarch / strcpy.S
blobc279d468cb94c2508e8c75591348a1a6cbbdc656
1 /* Multiple versions of strcpy
2    All versions must be listed in ifunc-impl-list.c.
3    Copyright (C) 2011-2015 Free Software Foundation, Inc.
4    Contributed by Intel Corporation.
5    This file is part of the GNU C Library.
7    The GNU C Library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2.1 of the License, or (at your option) any later version.
12    The GNU C Library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
17    You should have received a copy of the GNU Lesser General Public
18    License along with the GNU C Library; if not, see
19    <http://www.gnu.org/licenses/>.  */
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 STRCPY_IA32           __stpncpy_ia32
35 #  define __GI_STRCPY           __GI_stpncpy
36 #  define __GI___STRCPY         __GI___stpncpy
37 # else
38 #  define STRCPY_SSSE3  __stpcpy_ssse3
39 #  define STRCPY_SSE2           __stpcpy_sse2
40 #  define STRCPY_IA32           __stpcpy_ia32
41 #  define __GI_STRCPY           __GI_stpcpy
42 #  define __GI___STRCPY         __GI___stpcpy
43 # endif
44 #else
45 # ifdef USE_AS_STRNCPY
46 #  define STRCPY_SSSE3  __strncpy_ssse3
47 #  define STRCPY_SSE2           __strncpy_sse2
48 #  define STRCPY_IA32           __strncpy_ia32
49 #  define __GI_STRCPY           __GI_strncpy
50 # else
51 #  define STRCPY_SSSE3  __strcpy_ssse3
52 #  define STRCPY_SSE2           __strcpy_sse2
53 #  define STRCPY_IA32           __strcpy_ia32
54 #  define __GI_STRCPY           __GI_strcpy
55 # endif
56 #endif
59 /* Define multiple versions only for the definition in libc.  Don't
60    define multiple versions for strncpy in static library since we
61    need strncpy before the initialization happened.  */
62 #if IS_IN (libc)
64 # ifdef SHARED
65         .text
66 ENTRY(STRCPY)
67         .type   STRCPY, @gnu_indirect_function
68         pushl   %ebx
69         cfi_adjust_cfa_offset (4)
70         cfi_rel_offset (ebx, 0)
71         LOAD_PIC_REG(bx)
72         cmpl    $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx)
73         jne     1f
74         call    __init_cpu_features
75 1:      leal    STRCPY_IA32@GOTOFF(%ebx), %eax
76         testl   $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx)
77         jz      2f
78         leal    STRCPY_SSE2@GOTOFF(%ebx), %eax
79         testl   $bit_Fast_Unaligned_Load, FEATURE_OFFSET+index_Fast_Unaligned_Load+__cpu_features@GOTOFF(%ebx)
80         jnz     2f
81         testl   $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx)
82         jz      2f
83         leal    STRCPY_SSSE3@GOTOFF(%ebx), %eax
84 2:      popl    %ebx
85         cfi_adjust_cfa_offset (-4)
86         cfi_restore (ebx)
87         ret
88 END(STRCPY)
89 # else
91 ENTRY(STRCPY)
92         .type   STRCPY, @gnu_indirect_function
93         cmpl    $0, KIND_OFFSET+__cpu_features
94         jne     1f
95         call    __init_cpu_features
96 1:      leal    STRCPY_IA32, %eax
97         testl   $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features
98         jz      2f
99         leal    STRCPY_SSE2, %eax
100         testl   $bit_Fast_Unaligned_Load, FEATURE_OFFSET+index_Fast_Unaligned_Load+__cpu_features
101         jnz     2f
102         testl   $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features
103         jz      2f
104         leal    STRCPY_SSSE3, %eax
105 2:      ret
106 END(STRCPY)
108 # endif
110 # undef ENTRY
111 # define ENTRY(name) \
112         .type STRCPY_IA32, @function; \
113         .align 16; \
114         .globl STRCPY_IA32; \
115         .hidden STRCPY_IA32; \
116         STRCPY_IA32: cfi_startproc; \
117         CALL_MCOUNT
118 # undef END
119 # define END(name) \
120         cfi_endproc; .size STRCPY_IA32, .-STRCPY_IA32
122 # ifdef SHARED
123 #  undef libc_hidden_builtin_def
124 /* It doesn't make sense to send libc-internal strcpy calls through a PLT.
125    The speedup we get from using SSSE3 instruction is likely eaten away
126    by the indirect call in the PLT.  */
127 #  define libc_hidden_builtin_def(name) \
128         .globl __GI_STRCPY; __GI_STRCPY = STRCPY_IA32
129 #  undef libc_hidden_def
130 #  define libc_hidden_def(name) \
131         .globl __GI___STRCPY; __GI___STRCPY = STRCPY_IA32
133 # endif
134 #endif
136 #ifdef USE_AS_STPCPY
137 # ifdef USE_AS_STRNCPY
138 #  include "../../stpncpy.S"
139 # else
140 #  include "../../i586/stpcpy.S"
141 # endif
142 #else
143 # ifndef USE_AS_STRNCPY
144 #  include "../../i586/strcpy.S"
145 # endif
146 #endif