Prepare use if IFUNC functions outside libc.so.

We use a callback function into libc.so to get access to the data
structure with the information and have special versions of the test
macros which automatically use this function.
This commit is contained in:
Ulrich Drepper 2009-07-29 15:22:28 -07:00
parent 586fa886ad
commit 9a1d2d4555
3 changed files with 42 additions and 3 deletions

View File

@ -1,6 +1,6 @@
/* Support macros for making weak and strong aliases for symbols,
and for using symbol sets and linker warnings with GNU ld.
Copyright (C) 1995-1998, 2000-2006, 2008 Free Software Foundation, Inc.
Copyright (C) 1995-1998,2000-2006,2008,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -845,6 +845,17 @@ for linking")
} \
__asm__ (".type " #name ", %gnu_indirect_function");
/* The body of the function is supposed to use __get_cpu_features
which will, if necessary, initialize the data first. */
#define libm_ifunc(name, expr) \
extern void *name##_ifunc (void) __asm__ (#name); \
void *name##_ifunc (void) \
{ \
__typeof (name) *res = expr; \
return res; \
} \
__asm__ (".type " #name ", %gnu_indirect_function");
#ifdef HAVE_ASM_SET_DIRECTIVE
# define libc_ifunc_hidden_def1(local, name) \
__asm__ (declare_symbol_alias_1_stringify (ASM_GLOBAL_DIRECTIVE) \

View File

@ -86,3 +86,13 @@ __init_cpu_features (void)
else
__cpu_features.kind = arch_kind_other;
}
const struct cpu_features *
__get_cpu_features (void)
{
if (__cpu_features.kind == arch_kind_unknown)
__init_cpu_features ();
return &__cpu_features;
}

View File

@ -54,10 +54,28 @@ extern void __init_cpu_features (void) attribute_hidden;
__init_cpu_features (); \
while (0)
/* Used from outside libc.so to get access to the CPU features structure. */
extern const struct cpu_features *__get_cpu_features (void)
__attribute__ ((const));
/* Following are the feature tests used throughout libc. */
#define HAS_POPCOUNT \
#ifndef NOT_IN_libc
# define HAS_POPCOUNT \
((__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx & (1 << 23)) != 0)
#define HAS_SSE4_2 \
# define HAS_SSE4_2 \
((__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx & (1 << 20)) != 0)
# define HAS_FMA \
((__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx & (1 << 12)) != 0)
#else
# define HAS_POPCOUNT \
((__get_cpu_features ()->cpuid[COMMON_CPUID_INDEX_1].ecx & (1 << 23)) != 0)
# define HAS_SSE4_2 \
((__get_cpu_features ()->cpuid[COMMON_CPUID_INDEX_1].ecx & (1 << 20)) != 0)
# define HAS_FMA \
((__get_cpu_features ()->cpuid[COMMON_CPUID_INDEX_1].ecx & (1 << 12)) != 0)
#endif