]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/sparc/sparc-ifunc.h
sparc: Assume VIS3 support
[thirdparty/glibc.git] / sysdeps / sparc / sparc-ifunc.h
1 /* This file is part of the GNU C Library.
2 Copyright (C) 2012-2017 Free Software Foundation, Inc.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
17
18 #include <sysdep.h>
19
20 #ifdef __ASSEMBLER__
21
22 # ifdef SHARED
23
24 # define SPARC_ASM_IFUNC_DFLT(name, dflt) \
25 ENTRY (__##name) \
26 .type __##name, @gnu_indirect_function; \
27 SETUP_PIC_REG_LEAF(o3, o5); \
28 sethi %gdop_hix22(dflt), %o1; \
29 xor %o1, %gdop_lox10(dflt), %o1; \
30 add %o3, %o1, %o1; \
31 retl; \
32 mov %o1, %o0; \
33 END (__##name)
34
35 # define SPARC_ASM_IFUNC1(name, m1, f1, dflt) \
36 ENTRY (__##name) \
37 .type __##name, @gnu_indirect_function; \
38 SETUP_PIC_REG_LEAF(o3, o5); \
39 set m1, %o1; \
40 andcc %o0, %o1, %g0; \
41 be 9f; \
42 nop; \
43 sethi %gdop_hix22(f1), %o1; \
44 xor %o1, %gdop_lox10(f1), %o1; \
45 ba 10f; \
46 nop; \
47 9: sethi %gdop_hix22(dflt), %o1; \
48 xor %o1, %gdop_lox10(dflt), %o1; \
49 10: add %o3, %o1, %o1; \
50 retl; \
51 mov %o1, %o0; \
52 END (__##name)
53
54 # define SPARC_ASM_IFUNC2(name, m1, f1, m2, f2, dflt) \
55 ENTRY (__##name) \
56 .type __##name, @gnu_indirect_function; \
57 SETUP_PIC_REG_LEAF(o3, o5); \
58 set m1, %o1; \
59 andcc %o0, %o1, %g0; \
60 be 8f; \
61 nop; \
62 sethi %gdop_hix22(f1), %o1; \
63 xor %o1, %gdop_lox10(f1), %o1; \
64 ba 10f; \
65 nop; \
66 8: set m2, %o1; \
67 andcc %o0, %o1, %g0; \
68 be 9f; \
69 nop; \
70 sethi %gdop_hix22(f2), %o1; \
71 xor %o1, %gdop_lox10(f2), %o1; \
72 ba 10f; \
73 nop; \
74 9: sethi %gdop_hix22(dflt), %o1; \
75 xor %o1, %gdop_lox10(dflt), %o1; \
76 10: add %o3, %o1, %o1; \
77 retl; \
78 mov %o1, %o0; \
79 END (__##name)
80
81 # else /* SHARED */
82
83 # ifdef __arch64__
84 # define SET(SYM, TMP, REG) setx SYM, TMP, REG
85 # else
86 # define SET(SYM, TMP, REG) set SYM, REG
87 # endif
88
89 # define SPARC_ASM_IFUNC_DFLT(name, dflt) \
90 ENTRY (__##name) \
91 .type __##name, @gnu_indirect_function; \
92 SET(dflt, %g1, %o1); \
93 retl; \
94 mov %o1, %o0; \
95 END (__##name)
96
97 # define SPARC_ASM_IFUNC1(name, m1, f1, dflt) \
98 ENTRY (__##name) \
99 .type __##name, @gnu_indirect_function; \
100 set m1, %o1; \
101 andcc %o0, %o1, %g0; \
102 be 9f; \
103 nop; \
104 SET(f1, %g1, %o1); \
105 ba 10f; \
106 nop; \
107 9: SET(dflt, %g1, %o1); \
108 10: retl; \
109 mov %o1, %o0; \
110 END (__##name)
111
112 # define SPARC_ASM_IFUNC2(name, m1, f1, m2, f2, dflt) \
113 ENTRY (__##name) \
114 .type __##name, @gnu_indirect_function; \
115 set m1, %o1; \
116 andcc %o0, %o1, %g0; \
117 be 8f; \
118 nop; \
119 SET(f1, %g1, %o1); \
120 ba 10f; \
121 nop; \
122 8: set m2, %o1; \
123 andcc %o0, %o1, %g0; \
124 be 9f; \
125 nop; \
126 SET(f2, %g1, %o1); \
127 ba 10f; \
128 nop; \
129 9: SET(dflt, %g1, %o1); \
130 10: retl; \
131 mov %o1, %o0; \
132 END (__##name)
133
134 # endif /* SHARED */
135
136 #define SPARC_ASM_VIS2_IFUNC(name) \
137 SPARC_ASM_IFUNC1(name, HWCAP_SPARC_VIS2, \
138 __##name##_vis2, __##name##_generic)
139
140 #define SPARC_ASM_VIS3_IFUNC(name) \
141 SPARC_ASM_IFUNC1(name, HWCAP_SPARC_VIS3, \
142 __##name##_vis3, __##name##_generic)
143
144 #define SPARC_ASM_VIS3_VIS2_IFUNC(name) \
145 SPARC_ASM_IFUNC2(name, HWCAP_SPARC_VIS3, \
146 __##name##_vis3, \
147 HWCAP_SPARC_VIS2, \
148 __##name##_vis2, __##name##_generic)
149
150 #else /* __ASSEMBLER__ */
151 # define INIT_ARCH()
152
153 # define sparc_libc_ifunc_redirected(redirected_name, name, expr) \
154 __ifunc (redirected_name, name, expr(hwcap), int hwcap, INIT_ARCH)
155
156 # define sparc_libm_ifunc(name, expr) \
157 __ifunc (name, name, expr, int hwcap, libm_ifunc_init)
158
159 # define sparc_libc_ifunc(name, expr) sparc_libm_ifunc (name, expr)
160
161 /* It essentially does libc_hidden_builtin_def (name) and redirect
162 the internal redirected symbol to ifunc implementation. */
163 # if defined SHARED
164 # define sparc_ifunc_redirected_hidden_def(redirect_name, name) \
165 __hidden_ver1 (name, __GI_##name, redirect_name) \
166 __attribute__ ((visibility ("hidden")));
167 # else
168 # define sparc_ifunc_redirected_hidden_def(redirect_name, name)
169 # endif
170 #endif /* __ASSEMBLER__ */