* manual/time.texi (TZ Variable): POSIX.1 hour can be 24.
[glibc.git] / sysdeps / sparc / sparc-ifunc.h
blobf68161fc5f3b8fb3ca33aea7dfa6afc4ed9f27c6
1 /* This file is part of the GNU C Library.
2 Copyright (C) 2012-2013 Free Software Foundation, Inc.
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.
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.
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/>. */
18 #include <sysdep.h>
20 #ifdef __ASSEMBLER__
22 # ifdef SHARED
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)
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)
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)
81 # else /* SHARED */
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
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)
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)
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)
134 # endif /* SHARED */
136 #define SPARC_ASM_VIS2_IFUNC(name) \
137 SPARC_ASM_IFUNC1(name, HWCAP_SPARC_VIS2, \
138 __##name##_vis2, __##name##_generic)
140 # ifdef HAVE_AS_VIS3_SUPPORT
142 #define SPARC_ASM_VIS3_IFUNC(name) \
143 SPARC_ASM_IFUNC1(name, HWCAP_SPARC_VIS3, \
144 __##name##_vis3, __##name##_generic)
146 #define SPARC_ASM_VIS3_VIS2_IFUNC(name) \
147 SPARC_ASM_IFUNC2(name, HWCAP_SPARC_VIS3, \
148 __##name##_vis3, \
149 HWCAP_SPARC_VIS2, \
150 __##name##_vis2, __##name##_generic)
152 # else /* HAVE_AS_VIS3_SUPPORT */
154 #define SPARC_ASM_VIS3_IFUNC(name) \
155 SPARC_ASM_IFUNC_DFLT(name, __##name##_generic)
157 #define SPARC_ASM_VIS3_VIS2_IFUNC(name) \
158 SPARC_ASM_VIS2_IFUNC(name)
160 # endif /* HAVE_AS_VIS3_SUPPORT */
163 #else /* __ASSEMBLER__ */
165 # define sparc_libm_ifunc(name, expr) \
166 extern void *name##_ifunc (int) __asm__ (#name); \
167 void *name##_ifunc (int hwcap) \
169 __typeof (name) *res = expr; \
170 return res; \
172 __asm__ (".type " #name ", %gnu_indirect_function");
174 # define sparc_libc_ifunc(name, expr) sparc_libm_ifunc (name, expr)
176 #endif /* __ASSEMBLER__ */