1/* Multiple versions of strcat
2 All versions must be listed in ifunc-impl-list.c.
3 Copyright (C) 2009-2016 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
48ENTRY(STRCAT)
49 .type STRCAT, @gnu_indirect_function
50 LOAD_RTLD_GLOBAL_RO_RDX
51 leaq STRCAT_SSE2_UNALIGNED(%rip), %rax
52 HAS_ARCH_FEATURE (Fast_Unaligned_Load)
53 jnz 2f
54 leaq STRCAT_SSE2(%rip), %rax
55 HAS_CPU_FEATURE (SSSE3)
56 jz 2f
57 leaq STRCAT_SSSE3(%rip), %rax
582: ret
59END(STRCAT)
60
61# undef ENTRY
62# define ENTRY(name) \
63 .type STRCAT_SSE2, @function; \
64 .align 16; \
65 .globl STRCAT_SSE2; \
66 .hidden STRCAT_SSE2; \
67 STRCAT_SSE2: cfi_startproc; \
68 CALL_MCOUNT
69# undef END
70# define END(name) \
71 cfi_endproc; .size STRCAT_SSE2, .-STRCAT_SSE2
72# undef libc_hidden_builtin_def
73/* It doesn't make sense to send libc-internal strcat calls through a PLT.
74 The speedup we get from using SSSE3 instruction is likely eaten away
75 by the indirect call in the PLT. */
76# define libc_hidden_builtin_def(name) \
77 .globl __GI_STRCAT; __GI_STRCAT = STRCAT_SSE2
78# undef libc_hidden_def
79# define libc_hidden_def(name) \
80 .globl __GI___STRCAT; __GI___STRCAT = STRCAT_SSE2
81#endif
82
83#ifndef USE_AS_STRNCAT
84# include "../strcat.S"
85#endif
86