]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/x86_64/multiarch/strcat.S
531878016f4e61c2c611eb3e7f24a9d88f73ac57
[thirdparty/glibc.git] / sysdeps / x86_64 / multiarch / strcat.S
1 /* Multiple versions of strcat
2 All versions must be listed in ifunc-impl-list.c.
3 Copyright (C) 2009-2014 Free Software Foundation, Inc.
4 Contributed by Intel Corporation.
5 This file is part of the GNU C Library.
6
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.
11
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.
16
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/>. */
20
21 #include <sysdep.h>
22 #include <init-arch.h>
23
24 #ifndef USE_AS_STRNCAT
25 # ifndef STRCAT
26 # define STRCAT strcat
27 # endif
28 #endif
29
30 #ifdef USE_AS_STRNCAT
31 # define STRCAT_SSSE3 __strncat_ssse3
32 # define STRCAT_SSE2 __strncat_sse2
33 # define STRCAT_SSE2_UNALIGNED __strncat_sse2_unaligned
34 # define __GI_STRCAT __GI_strncat
35 # define __GI___STRCAT __GI___strncat
36 #else
37 # define STRCAT_SSSE3 __strcat_ssse3
38 # define STRCAT_SSE2 __strcat_sse2
39 # define STRCAT_SSE2_UNALIGNED __strcat_sse2_unaligned
40 # define __GI_STRCAT __GI_strcat
41 # define __GI___STRCAT __GI___strcat
42 #endif
43
44
45 /* Define multiple versions only for the definition in libc. */
46 #if IS_IN (libc)
47 .text
48 ENTRY(STRCAT)
49 .type STRCAT, @gnu_indirect_function
50 cmpl $0, __cpu_features+KIND_OFFSET(%rip)
51 jne 1f
52 call __init_cpu_features
53 1: leaq STRCAT_SSE2_UNALIGNED(%rip), %rax
54 testl $bit_Fast_Unaligned_Load, __cpu_features+FEATURE_OFFSET+index_Fast_Unaligned_Load(%rip)
55 jnz 2f
56 leaq STRCAT_SSE2(%rip), %rax
57 testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip)
58 jz 2f
59 leaq STRCAT_SSSE3(%rip), %rax
60 2: ret
61 END(STRCAT)
62
63 # undef ENTRY
64 # define ENTRY(name) \
65 .type STRCAT_SSE2, @function; \
66 .align 16; \
67 .globl STRCAT_SSE2; \
68 .hidden STRCAT_SSE2; \
69 STRCAT_SSE2: cfi_startproc; \
70 CALL_MCOUNT
71 # undef END
72 # define END(name) \
73 cfi_endproc; .size STRCAT_SSE2, .-STRCAT_SSE2
74 # undef libc_hidden_builtin_def
75 /* It doesn't make sense to send libc-internal strcat calls through a PLT.
76 The speedup we get from using SSSE3 instruction is likely eaten away
77 by the indirect call in the PLT. */
78 # define libc_hidden_builtin_def(name) \
79 .globl __GI_STRCAT; __GI_STRCAT = STRCAT_SSE2
80 # undef libc_hidden_def
81 # define libc_hidden_def(name) \
82 .globl __GI___STRCAT; __GI___STRCAT = STRCAT_SSE2
83 #endif
84
85 #ifndef USE_AS_STRNCAT
86 # include "../strcat.S"
87 #endif