glibc/sysdeps/sparc/sparc-ifunc.h
Adhemerval Zanella a55430cb0e sparc: Assume VIS3 support
This patch assumes VIS3 support by binutils, which is supported since
version 2.22.  This leads to some code simplification, mostly on
multiarch build where there is only one variant instead of previously
two (whether binutils supports VIS3 instructions or not).

For multiarch files where HAVE_AS_VIS3_SUPPORT was checked and
the default implementation was built with a different name, a new
file with (implementation with -generic appended) is added.

Checked on sparc64-linux-gnu and sparcv9-linux-gnu.

	* config.h.in (HAVE_AS_VIS3_SUPPORT): Remove check for VIS3 support.
	* sysdeps/sparc/configure.ac (HAVE_AS_VIS3_SUPPORT): Likewise.
	* sysdeps//sparc/sparc32/sparcv9/fpu/multiarch/s_fdim.c: Likewise.
	* sysdeps//sparc/sparc32/sparcv9/fpu/multiarch/s_fdimf.c: Likewise.
	* sysdeps//sparc/sparc32/sparcv9/fpu/multiarch/s_fma.c: Likewise.
	* sysdeps//sparc/sparc32/sparcv9/fpu/multiarch/s_fmaf.c: Likewise.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_ceil.c: Likewise.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_ceilf.c: Likewise.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_floor.c: Likewise.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_floorf.c: Likewise.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_fma.c: Likewise.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_fmaf.c: Likewise.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_trunc.c: Likewise.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_truncf.c: Likewise.
	* sysdeps/sparc/sparc-ifunc.h [!HAVE_AS_VIS3_SUPPORT]
	(SPARC_ASM_VIS3_IFUNC, SPARC_ASM_VIS3_VIS2_IFUNC): Remove macros.
	* sysdeps/sparc/sparc32/sparcv9/Makefile [$(have-as-vis3) != yes]
	(ASFLAGS.o, ASFLAGS-.os, ASFLAGS-.op, ASFLAGS-.oS): Remove rules.
	* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/Makefile
	($(have-as-vis3) == yes): Remove conditional.
	* sysdeps/sparc/sparc64/Makefile (($(have-as-vis3) == yes)):
	Likewise.
	* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdim-generic.c: New
	file.
	* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdimf-generic.c: New
	file.
	* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fma-generic.c: New
	file.
	* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fmaf-generic.c: New
	file.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c: New file.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_ceilf-generic.c: New file.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c: New file.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_floorf-generic.c: New file.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_fma-generic.c: New file.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_fmaf-generic.c: New file.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c: New file.
	* sysdeps/sparc/sparc64/fpu/multiarch/s_truncf-generic.c: New file.

Signed-off-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2017-11-29 08:18:00 -02:00

171 lines
4.5 KiB
C

/* 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)
#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 /* __ASSEMBLER__ */
# define INIT_ARCH()
# define sparc_libc_ifunc_redirected(redirected_name, name, expr) \
__ifunc (redirected_name, name, expr(hwcap), int hwcap, INIT_ARCH)
# define sparc_libm_ifunc(name, expr) \
__ifunc (name, name, expr, int hwcap, libm_ifunc_init)
# define sparc_libc_ifunc(name, expr) sparc_libm_ifunc (name, expr)
/* It essentially does libc_hidden_builtin_def (name) and redirect
the internal redirected symbol to ifunc implementation. */
# if defined SHARED
# define sparc_ifunc_redirected_hidden_def(redirect_name, name) \
__hidden_ver1 (name, __GI_##name, redirect_name) \
__attribute__ ((visibility ("hidden")));
# else
# define sparc_ifunc_redirected_hidden_def(redirect_name, name)
# endif
#endif /* __ASSEMBLER__ */