]>
Commit | Line | Data |
---|---|---|
5fa16e9b | 1 | /* Multiple versions of strcat |
b090e8ea | 2 | All versions must be listed in ifunc-impl-list.c. |
9a1d9254 | 3 | Copyright (C) 2011-2012 Free Software Foundation, Inc. |
5fa16e9b LD |
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 | |
59ba27a6 PE |
18 | License along with the GNU C Library; if not, see |
19 | <http://www.gnu.org/licenses/>. */ | |
5fa16e9b LD |
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_IA32 __strncat_ia32 | |
34 | # define __GI_STRCAT __GI_strncat | |
35 | #else | |
36 | # define STRCAT_SSSE3 __strcat_ssse3 | |
37 | # define STRCAT_SSE2 __strcat_sse2 | |
38 | # define STRCAT_IA32 __strcat_ia32 | |
39 | # define __GI_STRCAT __GI_strcat | |
40 | #endif | |
41 | ||
42 | ||
43 | /* Define multiple versions only for the definition in libc. Don't | |
44 | define multiple versions for strncat in static library since we | |
45 | need strncat before the initialization happened. */ | |
46 | #ifndef NOT_IN_libc | |
47 | ||
48 | # ifdef SHARED | |
5fa16e9b LD |
49 | .text |
50 | ENTRY(STRCAT) | |
51 | .type STRCAT, @gnu_indirect_function | |
52 | pushl %ebx | |
53 | cfi_adjust_cfa_offset (4) | |
54 | cfi_rel_offset (ebx, 0) | |
9a1d9254 | 55 | LOAD_PIC_REG(bx) |
5fa16e9b LD |
56 | cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) |
57 | jne 1f | |
58 | call __init_cpu_features | |
59 | 1: leal STRCAT_IA32@GOTOFF(%ebx), %eax | |
60 | testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) | |
61 | jz 2f | |
62 | leal STRCAT_SSE2@GOTOFF(%ebx), %eax | |
63 | testl $bit_Fast_Unaligned_Load, FEATURE_OFFSET+index_Fast_Unaligned_Load+__cpu_features@GOTOFF(%ebx) | |
64 | jnz 2f | |
65 | testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) | |
66 | jz 2f | |
67 | leal STRCAT_SSSE3@GOTOFF(%ebx), %eax | |
68 | 2: popl %ebx | |
69 | cfi_adjust_cfa_offset (-4) | |
70 | cfi_restore (ebx) | |
71 | ret | |
72 | END(STRCAT) | |
73 | # else | |
74 | ||
75 | ENTRY(STRCAT) | |
76 | .type STRCAT, @gnu_indirect_function | |
77 | cmpl $0, KIND_OFFSET+__cpu_features | |
78 | jne 1f | |
79 | call __init_cpu_features | |
80 | 1: leal STRCAT_IA32, %eax | |
81 | testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features | |
82 | jz 2f | |
83 | leal STRCAT_SSE2, %eax | |
84 | testl $bit_Fast_Unaligned_Load, FEATURE_OFFSET+index_Fast_Unaligned_Load+__cpu_features | |
85 | jnz 2f | |
86 | testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features | |
87 | jz 2f | |
88 | leal STRCAT_SSSE3, %eax | |
89 | 2: ret | |
90 | END(STRCAT) | |
91 | ||
92 | # endif | |
93 | ||
94 | # undef ENTRY | |
95 | # define ENTRY(name) \ | |
96 | .type STRCAT_IA32, @function; \ | |
97 | .align 16; \ | |
b090e8ea L |
98 | .globl STRCAT_IA32; \ |
99 | .hidden STRCAT_IA32; \ | |
5fa16e9b LD |
100 | STRCAT_IA32: cfi_startproc; \ |
101 | CALL_MCOUNT | |
102 | # undef END | |
103 | # define END(name) \ | |
104 | cfi_endproc; .size STRCAT_IA32, .-STRCAT_IA32 | |
105 | ||
106 | # ifdef SHARED | |
107 | # undef libc_hidden_builtin_def | |
108 | /* It doesn't make sense to send libc-internal strcat calls through a PLT. | |
109 | The speedup we get from using SSSE3 instruction is likely eaten away | |
110 | by the indirect call in the PLT. */ | |
111 | # define libc_hidden_builtin_def(name) \ | |
112 | .globl __GI_STRCAT; __GI_STRCAT = STRCAT_IA32 | |
113 | # undef libc_hidden_def | |
114 | # define libc_hidden_def(name) \ | |
115 | .globl __GI___STRCAT; __GI___STRCAT = STRCAT_IA32 | |
116 | ||
117 | # endif | |
118 | #endif | |
119 | ||
120 | #ifndef USE_AS_STRNCAT | |
121 | # include "../../i486/strcat.S" | |
122 | #endif |