]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/sparc/sparc-ifunc.h
Add support for sparc cryptographic hash opcodes.
[thirdparty/glibc.git] / sysdeps / sparc / sparc-ifunc.h
1 /* This file is part of the GNU C Library.
2 Copyright (C) 2012 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 # else /* SHARED */
55
56 # ifdef __arch64__
57 # define SET(SYM, TMP, REG) setx SYM, TMP, REG
58 # else
59 # define SET(SYM, TMP, REG) set SYM, REG
60 # endif
61
62 # define SPARC_ASM_IFUNC_DFLT(name, dflt) \
63 ENTRY (__##name) \
64 .type __##name, @gnu_indirect_function; \
65 SET(dflt, %g1, %o1); \
66 retl; \
67 mov %o1, %o0; \
68 END (__##name)
69
70 # define SPARC_ASM_IFUNC1(name, m1, f1, dflt) \
71 ENTRY (__##name) \
72 .type __##name, @gnu_indirect_function; \
73 set m1, %o1; \
74 andcc %o0, %o1, %g0; \
75 be 9f; \
76 nop; \
77 SET(f1, %g1, %o1); \
78 ba 10f; \
79 nop; \
80 9: SET(dflt, %g1, %o1); \
81 10: retl; \
82 mov %o1, %o0; \
83 END (__##name)
84
85 # endif /* SHARED */
86
87 # ifdef HAVE_AS_VIS3_SUPPORT
88
89 #define SPARC_ASM_VIS3_IFUNC(name) \
90 SPARC_ASM_IFUNC1(name, HWCAP_SPARC_VIS3, \
91 __##name##_vis3, __##name##_generic)
92
93 # else /* HAVE_AS_VIS3_SUPPORT */
94
95 #define SPARC_ASM_VIS3_IFUNC(name) \
96 SPARC_ASM_IFUNC_DFLT(name, __##name##_generic)
97
98 # endif /* HAVE_AS_VIS3_SUPPORT */
99
100
101 #else /* __ASSEMBLER__ */
102
103 # define sparc_libm_ifunc(name, expr) \
104 extern void *name##_ifunc (int) __asm__ (#name); \
105 void *name##_ifunc (int hwcap) \
106 { \
107 __typeof (name) *res = expr; \
108 return res; \
109 } \
110 __asm__ (".type " #name ", %gnu_indirect_function");
111
112 # define sparc_libc_ifunc(name, expr) sparc_libm_ifunc (name, expr)
113
114 #endif /* __ASSEMBLER__ */