about summary refs log tree commit diff
path: root/REORG.TODO/sysdeps/sparc/sparc-ifunc.h
diff options
context:
space:
mode:
Diffstat (limited to 'REORG.TODO/sysdeps/sparc/sparc-ifunc.h')
-rw-r--r--REORG.TODO/sysdeps/sparc/sparc-ifunc.h176
1 files changed, 176 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/sparc/sparc-ifunc.h b/REORG.TODO/sysdeps/sparc/sparc-ifunc.h
new file mode 100644
index 0000000000..8cc86ff5e1
--- /dev/null
+++ b/REORG.TODO/sysdeps/sparc/sparc-ifunc.h
@@ -0,0 +1,176 @@
+/* This file is part of the GNU C Library.
+   Copyright (C) 2012-2017 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+# ifdef SHARED
+
+#  define SPARC_ASM_IFUNC_DFLT(name, dflt)		\
+ENTRY (__##name)					\
+	.type	__##name, @gnu_indirect_function;	\
+	SETUP_PIC_REG_LEAF(o3, o5);			\
+	sethi	%gdop_hix22(dflt), %o1;			\
+	xor	%o1, %gdop_lox10(dflt), %o1;		\
+	add	%o3, %o1, %o1;				\
+	retl;						\
+	 mov	%o1, %o0;				\
+END (__##name)
+
+#  define SPARC_ASM_IFUNC1(name, m1, f1, dflt)		\
+ENTRY (__##name)					\
+	.type	__##name, @gnu_indirect_function;	\
+	SETUP_PIC_REG_LEAF(o3, o5);			\
+	set	m1, %o1;				\
+	andcc	%o0, %o1, %g0;				\
+	be	9f;					\
+	 nop;						\
+	sethi	%gdop_hix22(f1), %o1;			\
+	xor	%o1, %gdop_lox10(f1), %o1;		\
+	ba	10f;					\
+	 nop;						\
+9:	sethi	%gdop_hix22(dflt), %o1;			\
+	xor	%o1, %gdop_lox10(dflt), %o1;		\
+10:	add	%o3, %o1, %o1;				\
+	retl;						\
+	 mov	%o1, %o0;				\
+END (__##name)
+
+#  define SPARC_ASM_IFUNC2(name, m1, f1, m2, f2, dflt)	\
+ENTRY (__##name)					\
+	.type	__##name, @gnu_indirect_function;	\
+	SETUP_PIC_REG_LEAF(o3, o5);			\
+	set	m1, %o1;				\
+	andcc	%o0, %o1, %g0;				\
+	be	8f;					\
+	 nop;						\
+	sethi	%gdop_hix22(f1), %o1;			\
+	xor	%o1, %gdop_lox10(f1), %o1;		\
+	ba	10f;					\
+	 nop;						\
+8:	set	m2, %o1;				\
+	andcc	%o0, %o1, %g0;				\
+	be	9f;					\
+	 nop;						\
+	sethi	%gdop_hix22(f2), %o1;			\
+	xor	%o1, %gdop_lox10(f2), %o1;		\
+	ba	10f;					\
+	 nop;						\
+9:	sethi	%gdop_hix22(dflt), %o1;			\
+	xor	%o1, %gdop_lox10(dflt), %o1;		\
+10:	add	%o3, %o1, %o1;				\
+	retl;						\
+	 mov	%o1, %o0;				\
+END (__##name)
+
+# else /* SHARED */
+
+# ifdef __arch64__
+#  define SET(SYM, TMP, REG)	setx SYM, TMP, REG
+# else
+#  define SET(SYM, TMP, REG)	set SYM, REG
+# endif
+
+#  define SPARC_ASM_IFUNC_DFLT(name, dflt)		\
+ENTRY (__##name)					\
+	.type	__##name, @gnu_indirect_function;	\
+	SET(dflt, %g1, %o1);				\
+	retl;						\
+	 mov	%o1, %o0;				\
+END (__##name)
+
+#  define SPARC_ASM_IFUNC1(name, m1, f1, dflt)		\
+ENTRY (__##name)					\
+	.type	__##name, @gnu_indirect_function;	\
+	set	m1, %o1;				\
+	andcc	%o0, %o1, %g0;				\
+	be	9f;					\
+	 nop;						\
+	SET(f1, %g1, %o1);				\
+	ba	10f;					\
+	 nop;						\
+9:	SET(dflt, %g1, %o1);				\
+10:	retl;						\
+	 mov	%o1, %o0;				\
+END (__##name)
+
+#  define SPARC_ASM_IFUNC2(name, m1, f1, m2, f2, dflt)	\
+ENTRY (__##name)					\
+	.type	__##name, @gnu_indirect_function;	\
+	set	m1, %o1;				\
+	andcc	%o0, %o1, %g0;				\
+	be	8f;					\
+	 nop;						\
+	SET(f1, %g1, %o1);				\
+	ba	10f;					\
+	 nop;						\
+8:	set	m2, %o1;				\
+	andcc	%o0, %o1, %g0;				\
+	be	9f;					\
+	 nop;						\
+	SET(f2, %g1, %o1);				\
+	ba	10f;					\
+	 nop;						\
+9:	SET(dflt, %g1, %o1);				\
+10:	retl;						\
+	 mov	%o1, %o0;				\
+END (__##name)
+
+# endif /* SHARED */
+
+#define SPARC_ASM_VIS2_IFUNC(name)			\
+	SPARC_ASM_IFUNC1(name, HWCAP_SPARC_VIS2,	\
+			 __##name##_vis2, __##name##_generic)
+
+# ifdef HAVE_AS_VIS3_SUPPORT
+
+#define SPARC_ASM_VIS3_IFUNC(name)			\
+	SPARC_ASM_IFUNC1(name, HWCAP_SPARC_VIS3,	\
+			 __##name##_vis3, __##name##_generic)
+
+#define SPARC_ASM_VIS3_VIS2_IFUNC(name)			\
+	SPARC_ASM_IFUNC2(name, HWCAP_SPARC_VIS3,	\
+			 __##name##_vis3,		\
+			 HWCAP_SPARC_VIS2,		\
+			 __##name##_vis2, __##name##_generic)
+
+# else /* HAVE_AS_VIS3_SUPPORT */
+
+#define SPARC_ASM_VIS3_IFUNC(name)			\
+	SPARC_ASM_IFUNC_DFLT(name, __##name##_generic)
+
+#define SPARC_ASM_VIS3_VIS2_IFUNC(name)			\
+	SPARC_ASM_VIS2_IFUNC(name)
+
+# endif /* HAVE_AS_VIS3_SUPPORT */
+
+
+#else	/* __ASSEMBLER__ */
+
+# define sparc_libm_ifunc(name, expr)					\
+  extern void *name##_ifunc (int) __asm__ (#name);			\
+  void *name##_ifunc (int hwcap)					\
+  {									\
+    __typeof (name) *res = expr;					\
+    return res;								\
+  }									\
+  __asm__ (".type " #name ", %gnu_indirect_function");
+
+# define sparc_libc_ifunc(name, expr) sparc_libm_ifunc (name, expr)
+
+#endif	/* __ASSEMBLER__ */