This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: Test optimizations for multiple architectures


With IFUNC functions, glibc testsuite can only test one implementation.
This patch adds --enable-test-multi-arch, which is disabled by default.
--enable-test-multi-arch will enable testing for all implementations
supported on build machine.  This prove of concept implements testing
for 64bit memcpy. On Intel Core i7, I got


                       	simple_memcpy	builtin_memcpy	memcpy	__memcpy_ssse3_back	__memcpy_ssse3	__memcpy_sse2
Length    1, alignment  0/ 0:	0	0	0	0	0	0
Length    1, alignment  0/ 0:	0	0	0	0	0	0
Length    1, alignment  0/ 0:	0	0	0	0	0	0
Length    1, alignment  0/ 0:	0	0	0	0	0	0
Length    2, alignment  0/ 0:	0	0	0	0	0	0
Length    2, alignment  1/ 0:	0	0	0	0	0	0
Length    2, alignment  0/ 1:	0	0	0	0	0	0
Length    2, alignment  1/ 1:	0	0	0	0	0	0
Length    4, alignment  0/ 0:	0	0	0	0	0	0

Any comments?

Thanks.


H.J.
---
2010-11-11  H.J. Lu  <hongjiu.lu@intel.com>

	* config.h.in (TEST_MULTIARCH): New.
	* config.make.in (test-multi-arch): Likewise.

	* configure.in: Add --enable-test-multi-arch.
	* configure: Regenerated.

	* debug/test-stpcpy_chk.c (TEST_NAME): New.
	* debug/test-strcpy_chk.c (TEST_NAME): Likewise.
	* string/test-memccpy.c (TEST_NAME): Likewise.
	* string/test-memchr.c (TEST_NAME): Likewise.
	* string/test-memcmp.c (TEST_NAME): Likewise.
	* string/test-memcpy.c (TEST_NAME): Likewise.
	* string/test-memmem.c (TEST_NAME): Likewise.
	* string/test-memmove.c (TEST_NAME): Likewise.
	* string/test-mempcpy.c (TEST_NAME): Likewise.
	* string/test-memset.c (TEST_NAME): Likewise.
	* string/test-stpcpy.c (TEST_NAME): Likewise.
	* string/test-stpncpy.c (TEST_NAME): Likewise.
	* string/test-strcasecmp.c (TEST_NAME): Likewise.
	* string/test-strcasestr.c (TEST_NAME): Likewise.
	* string/test-strcat.c (TEST_NAME): Likewise.
	* string/test-strchr.c (TEST_NAME): Likewise.
	* string/test-strcmp.c(TEST_NAME): Likewise.
	* string/test-strcpy.c (TEST_NAME): Likewise.
	* string/test-strcspn.c (TEST_NAME): Likewise.
	* string/test-strlen.c (TEST_NAME): Likewise.
	* string/test-strncasecmp.c (TEST_NAME): Likewise.
	* string/test-strncmp.c (TEST_NAME): Likewise.
	* string/test-strncpy.c (TEST_NAME): Likewise.
	* string/test-strnlen.c (TEST_NAME): Likewise.
	* string/test-strpbrk.c (TEST_NAME): Likewise.
	* string/test-strrchr.c (TEST_NAME): Likewise.
	* string/test-strspn.c (TEST_NAME): Likewise.
	* string/test-strstr.c (TEST_NAME): Likewise.

	* include/libc-test.h: New.
	* sysdeps/generic/libc-test.c: Likewise.
	* sysdeps/x86_64/multiarch/libc-test.c: Likewise.

	* string/Makefile: Include ../Makeconfig.
	(routines): Add libc-test if $(test-multi-arch) is yes.

	* string/test-string.h: Include <libc-test.h>.
	(FOR_EACH_IMPL): Support func_list.
	(func_list): New.
	(impl_count): Likewise.
	(impl_array); Likewise.
	(test_init): __libc_func to initialize func_list if
	TEST_MULTIARCH is defined.

	* string/Versions: Add __libc_func if TEST_MULTIARCH is defined.

	* sysdeps/x86_64/multiarch/memcpy.S (__memcpy_sse2): Make it
	global and hidden.

diff --git a/config.h.in b/config.h.in
index 18bf01a..7501aee 100644
--- a/config.h.in
+++ b/config.h.in
@@ -201,6 +201,9 @@
 /* Define if multi-arch DSOs should be generated.  */
 #undef USE_MULTIARCH
 
+/* Define if optimizations for multiple architectures should be tested.  */
+#undef TEST_MULTIARCH
+
 /*
  */
 
diff --git a/config.make.in b/config.make.in
index efffee4..87aafb8 100644
--- a/config.make.in
+++ b/config.make.in
@@ -76,6 +76,7 @@ oldest-abi = @oldest_abi@
 no-whole-archive = @no_whole_archive@
 exceptions = @exceptions@
 multi-arch = @multi_arch@
+test-multi-arch = @test_multi_arch@
 
 mach-interface-list = @mach_interface_list@
 
diff --git a/configure b/configure
index eae35ba..ab31c22 100755
--- a/configure
+++ b/configure
@@ -684,6 +684,7 @@ add_on_subdirs
 add_ons
 libc_cv_nss_crypt
 experimental_malloc
+test_multi_arch
 all_warnings
 force_install
 bindnow
@@ -782,6 +783,7 @@ enable_force_install
 enable_kernel
 enable_all_warnings
 enable_multi_arch
+enable_test_multi_arch
 enable_experimental_malloc
 enable_nss_crypt
 with_cpu
@@ -1441,6 +1443,9 @@ Optional Features:
   --enable-all-warnings   enable all useful warnings gcc can issue
   --enable-multi-arch     enable single DSO with optimizations for multiple
                           architectures
+  --enable-test-multi-arch
+                          enable test of optimizations for multiple
+                          architectures
   --enable-experimental-malloc
                           enable experimental malloc features
   --enable-nss-crypt      enable libcrypt to use nss
@@ -3750,6 +3755,19 @@ else
 fi
 
 
+# Check whether --enable-test-multi-arch was given.
+if test "${enable_test_multi_arch+set}" = set; then :
+  enableval=$enable_test_multi_arch; test_multi_arch=$enableval
+else
+  test_multi_arch=no
+fi
+
+if test x"$test_multi_arch" != xno; then
+  $as_echo "#define TEST_MULTIARCH 1" >>confdefs.h
+
+fi
+
+
 # Check whether --enable-experimental-malloc was given.
 if test "${enable_experimental_malloc+set}" = set; then :
   enableval=$enable_experimental_malloc; experimental_malloc=$enableval
diff --git a/configure.in b/configure.in
index d8cd5f1..f8f7602 100644
--- a/configure.in
+++ b/configure.in
@@ -274,6 +274,16 @@ AC_ARG_ENABLE([multi-arch],
 	      [multi_arch=$enableval],
 	      [multi_arch=default])
 
+AC_ARG_ENABLE([test-multi-arch],
+	      AC_HELP_STRING([--enable-test-multi-arch],
+			     [enable test of optimizations for multiple architectures]),
+	      [test_multi_arch=$enableval],
+	      [test_multi_arch=no])
+if test x"$test_multi_arch" != xno; then
+  AC_DEFINE(TEST_MULTIARCH)
+fi
+AC_SUBST(test_multi_arch)
+
 AC_ARG_ENABLE([experimental-malloc],
 	      AC_HELP_STRING([--enable-experimental-malloc],
 			     [enable experimental malloc features]),
diff --git a/debug/test-stpcpy_chk.c b/debug/test-stpcpy_chk.c
index d717ca7..1f8f588 100644
--- a/debug/test-stpcpy_chk.c
+++ b/debug/test-stpcpy_chk.c
@@ -20,6 +20,7 @@
 
 #define STRCPY_RESULT(dst, len) ((dst) + (len))
 #define TEST_MAIN
+#define TEST_NAME "stpcpy_chk"
 #include "../string/test-string.h"
 
 extern void __attribute__ ((noreturn)) __chk_fail (void);
diff --git a/debug/test-strcpy_chk.c b/debug/test-strcpy_chk.c
index e08141d..05bd0cb 100644
--- a/debug/test-strcpy_chk.c
+++ b/debug/test-strcpy_chk.c
@@ -21,6 +21,7 @@
 #ifndef STRCPY_RESULT
 # define STRCPY_RESULT(dst, len) dst
 # define TEST_MAIN
+# define TEST_NAME "strcpy_chk"
 # include "../string/test-string.h"
 
 extern void __attribute__ ((noreturn)) __chk_fail (void);
diff --git a/include/libc-test.h b/include/libc-test.h
new file mode 100644
index 0000000..edd814f
--- /dev/null
+++ b/include/libc-test.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2010 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
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _LIBC_TEST_H
+#define _LIBC_TEST_H	1
+
+struct libc_func_test
+{
+  /* The name of function to be tested.  */
+  const char *name;
+  /* The address of function to be tested.  */
+  void (*fn) (void);
+};
+
+/* Return the NULL terminated array of functions.  */
+extern const struct libc_func_test *__libc_func (const char *);
+
+#endif /* libc-symbols.h */
diff --git a/string/Makefile b/string/Makefile
index f836f59..7439f45 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -42,6 +42,12 @@ routines	:= strcat strchr strcmp strcoll strcpy strcspn		\
 		   strcoll_l strxfrm_l string-inlines memrchr		\
 		   xpg-strerror strerror_l
 
+include ../Makeconfig
+
+ifeq (yes,$(test-multi-arch))
+routines += libc-test
+endif
+
 # Gcc internally generates calls to unbounded memcpy and memset
 # for -fbounded-pointer compiles.  Glibc uses memchr for explicit checks.
 o-objects.ob	:= memcpy.o memset.o memchr.o
diff --git a/string/Versions b/string/Versions
index f145fd3..9cecf29 100644
--- a/string/Versions
+++ b/string/Versions
@@ -80,4 +80,9 @@ libc {
   GLIBC_2.6 {
     strerror_l;
   }
+%ifdef TEST_MULTIARCH
+  GLIBC_PRIVATE {
+    __libc_func;
+  }
+%endif
 }
diff --git a/string/test-memccpy.c b/string/test-memccpy.c
index 2653263..c5676cf 100644
--- a/string/test-memccpy.c
+++ b/string/test-memccpy.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "memccpy"
 #include "test-string.h"
 
 void *simple_memccpy (void *, const void *, int, size_t);
diff --git a/string/test-memchr.c b/string/test-memchr.c
index cd9a01e..ab510ef 100644
--- a/string/test-memchr.c
+++ b/string/test-memchr.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "memchr"
 #include "test-string.h"
 
 typedef char *(*proto_t) (const char *, int, size_t);
diff --git a/string/test-memcmp.c b/string/test-memcmp.c
index 3040e21..4fbfa54 100644
--- a/string/test-memcmp.c
+++ b/string/test-memcmp.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "memcmp"
 #include "test-string.h"
 
 typedef int (*proto_t) (const char *, const char *, size_t);
diff --git a/string/test-memcpy.c b/string/test-memcpy.c
index 7b0723a..5b5c657 100644
--- a/string/test-memcpy.c
+++ b/string/test-memcpy.c
@@ -22,6 +22,7 @@
 # define MEMCPY_RESULT(dst, len) dst
 # define MIN_PAGE_SIZE 131072
 # define TEST_MAIN
+# define TEST_NAME "memcpy"
 # include "test-string.h"
 
 char *simple_memcpy (char *, const char *, size_t);
diff --git a/string/test-memmem.c b/string/test-memmem.c
index 91b661b..4402623 100644
--- a/string/test-memmem.c
+++ b/string/test-memmem.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "memmem"
 #define BUF1PAGES 20
 #define ITERATIONS 500
 #include "test-string.h"
diff --git a/string/test-memmove.c b/string/test-memmove.c
index 2f3a8f7..cf3fa1e 100644
--- a/string/test-memmove.c
+++ b/string/test-memmove.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "memmove"
 #include "test-string.h"
 
 typedef char *(*proto_t) (char *, const char *, size_t);
diff --git a/string/test-mempcpy.c b/string/test-mempcpy.c
index f8b0267..9bf2e86 100644
--- a/string/test-mempcpy.c
+++ b/string/test-mempcpy.c
@@ -20,6 +20,7 @@
 
 #define MEMCPY_RESULT(dst, len) (dst) + (len)
 #define TEST_MAIN
+#define TEST_NAME "mempcpy"
 #include "test-string.h"
 
 char *simple_mempcpy (char *, const char *, size_t);
diff --git a/string/test-memset.c b/string/test-memset.c
index 601ace4..cdc51d0 100644
--- a/string/test-memset.c
+++ b/string/test-memset.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "memset"
 #define MIN_PAGE_SIZE 131072
 #include "test-string.h"
 
diff --git a/string/test-stpcpy.c b/string/test-stpcpy.c
index c8d4cc4..0582aaa 100644
--- a/string/test-stpcpy.c
+++ b/string/test-stpcpy.c
@@ -20,6 +20,7 @@
 
 #define STRCPY_RESULT(dst, len) ((dst) + (len))
 #define TEST_MAIN
+#define TEST_NAME "stpcpy"
 #include "test-string.h"
 
 char *simple_stpcpy (char *, const char *);
diff --git a/string/test-stpncpy.c b/string/test-stpncpy.c
index 8784588..115cf79 100644
--- a/string/test-stpncpy.c
+++ b/string/test-stpncpy.c
@@ -20,6 +20,7 @@
 
 #define STRNCPY_RESULT(dst, len, n) ((dst) + ((len) > (n) ? (n) : (len)))
 #define TEST_MAIN
+#define TEST_NAME "stpncpy"
 #include "test-string.h"
 
 char *simple_stpncpy (char *, const char *, size_t);
diff --git a/string/test-strcasecmp.c b/string/test-strcasecmp.c
index 7d1d110..261af13 100644
--- a/string/test-strcasecmp.c
+++ b/string/test-strcasecmp.c
@@ -20,6 +20,7 @@
 
 #include <ctype.h>
 #define TEST_MAIN
+#define TEST_NAME "strcasecmp"
 #include "test-string.h"
 
 typedef int (*proto_t) (const char *, const char *);
diff --git a/string/test-strcasestr.c b/string/test-strcasestr.c
index edc41f3..9981c23 100644
--- a/string/test-strcasestr.c
+++ b/string/test-strcasestr.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "strcasestr"
 #include "test-string.h"
 
 
diff --git a/string/test-strcat.c b/string/test-strcat.c
index 4437520..83b133a 100644
--- a/string/test-strcat.c
+++ b/string/test-strcat.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "strcat"
 #include "test-string.h"
 
 typedef char *(*proto_t) (char *, const char *);
diff --git a/string/test-strchr.c b/string/test-strchr.c
index cf25b44..200327c 100644
--- a/string/test-strchr.c
+++ b/string/test-strchr.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "strchr"
 #include "test-string.h"
 
 typedef char *(*proto_t) (const char *, int);
diff --git a/string/test-strcmp.c b/string/test-strcmp.c
index 769e982..71242e3 100644
--- a/string/test-strcmp.c
+++ b/string/test-strcmp.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "strcmp"
 #include "test-string.h"
 
 typedef int (*proto_t) (const char *, const char *);
diff --git a/string/test-strcpy.c b/string/test-strcpy.c
index 6a2ea25..7a4e3be 100644
--- a/string/test-strcpy.c
+++ b/string/test-strcpy.c
@@ -21,6 +21,7 @@
 #ifndef STRCPY_RESULT
 # define STRCPY_RESULT(dst, len) dst
 # define TEST_MAIN
+# define TEST_NAME "strcpy"
 # include "test-string.h"
 
 char *simple_strcpy (char *, const char *);
diff --git a/string/test-strcspn.c b/string/test-strcspn.c
index b563179..403a2fd 100644
--- a/string/test-strcspn.c
+++ b/string/test-strcspn.c
@@ -21,6 +21,7 @@
 #define STRPBRK_RESULT(s, pos) (pos)
 #define RES_TYPE size_t
 #define TEST_MAIN
+#define TEST_NAME "strcspn"
 #include "test-string.h"
 
 typedef size_t (*proto_t) (const char *, const char *);
diff --git a/string/test-string.h b/string/test-string.h
index 1aea4c9..93773e3 100644
--- a/string/test-string.h
+++ b/string/test-string.h
@@ -48,6 +48,7 @@ extern impl_t __start_impls[], __stop_impls[];
 #include <error.h>
 #include <errno.h>
 #include <time.h>
+#include <libc-test.h>
 #define GL(x) _##x
 #define GLRO(x) _##x
 #include <hp-timing.h>
@@ -105,7 +106,38 @@ size_t iterations = 100000;
   (* (proto_t) (impl)->fn) (__VA_ARGS__)
 
 #define FOR_EACH_IMPL(impl, notall) \
-  for (impl_t *impl = __start_impls; impl < __stop_impls; ++impl)	\
+  impl_t *impl;								\
+  int count;								\
+  if (impl_count == -1)							\
+    {									\
+      impl_count = 0;							\
+      for (impl = __start_impls; impl < __stop_impls; ++impl)		\
+	impl_count++;							\
+      if (func_list)							\
+	{								\
+	  const struct libc_func_test *p;				\
+	  for (p = func_list; p && p->name; ++p)			\
+	    impl_count++;						\
+	  if (impl_count)						\
+	    {								\
+	      impl_t *a;						\
+	      a = impl_array = malloc (impl_count * sizeof (impl_t));	\
+	      for (impl = __start_impls; impl < __stop_impls; ++impl)	\
+	        *a++ = *impl;						\
+	      for (p = func_list; p && p->name; ++p)			\
+		{							\
+		  a->name = p->name;					\
+		  a->fn = p->fn;					\
+		  a->test = 1;						\
+		  a++;							\
+		}							\
+	    }								\
+	}								\
+      else								\
+        impl_array = __start_impls;					\
+    }									\
+  impl = impl_array;							\
+  for (count = 0; count < impl_count; ++count, ++impl)			\
     if (!notall || impl->test)
 
 #define HP_TIMING_BEST(best_time, start, end)	\
@@ -122,9 +154,17 @@ size_t iterations = 100000;
 # define BUF1PAGES 1
 #endif
 
+static const struct libc_func_test *func_list;
+static int impl_count = -1;
+static impl_t *impl_array;
+
 static void
 test_init (void)
 {
+#ifdef TEST_MULTIARCH 
+  func_list = __libc_func (TEST_NAME);
+#endif
+
   page_size = 2 * getpagesize ();
 #ifdef MIN_PAGE_SIZE
   if (page_size < MIN_PAGE_SIZE)
diff --git a/string/test-strlen.c b/string/test-strlen.c
index e01befb..feb1c5d 100644
--- a/string/test-strlen.c
+++ b/string/test-strlen.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "strlen"
 #include "test-string.h"
 
 typedef size_t (*proto_t) (const char *);
diff --git a/string/test-strncasecmp.c b/string/test-strncasecmp.c
index daff6ed..9ec8955 100644
--- a/string/test-strncasecmp.c
+++ b/string/test-strncasecmp.c
@@ -20,6 +20,7 @@
 
 #include <ctype.h>
 #define TEST_MAIN
+#define TEST_NAME "strncasecmp"
 #include "test-string.h"
 
 typedef int (*proto_t) (const char *, const char *, size_t);
diff --git a/string/test-strncmp.c b/string/test-strncmp.c
index 3687879..891acb0 100644
--- a/string/test-strncmp.c
+++ b/string/test-strncmp.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "strncmp"
 #include "test-string.h"
 
 typedef int (*proto_t) (const char *, const char *, size_t);
diff --git a/string/test-strncpy.c b/string/test-strncpy.c
index d7a714c..f89b27d 100644
--- a/string/test-strncpy.c
+++ b/string/test-strncpy.c
@@ -21,6 +21,7 @@
 #ifndef STRNCPY_RESULT
 # define STRNCPY_RESULT(dst, len, n) dst
 # define TEST_MAIN
+# define TEST_NAME "strncpy"
 # include "test-string.h"
 
 char *simple_strncpy (char *, const char *, size_t);
diff --git a/string/test-strnlen.c b/string/test-strnlen.c
index cb8c80f..d078729 100644
--- a/string/test-strnlen.c
+++ b/string/test-strnlen.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "strnlen"
 #include "test-string.h"
 
 typedef size_t (*proto_t) (const char *, size_t);
diff --git a/string/test-strpbrk.c b/string/test-strpbrk.c
index f3ed208..76ac8c7 100644
--- a/string/test-strpbrk.c
+++ b/string/test-strpbrk.c
@@ -22,6 +22,7 @@
 # define STRPBRK_RESULT(s, pos) ((s)[(pos)] ? (s) + (pos) : NULL)
 # define RES_TYPE char *
 # define TEST_MAIN
+# define TEST_NAME "strpbrk"
 # include "test-string.h"
 
 typedef char *(*proto_t) (const char *, const char *);
diff --git a/string/test-strrchr.c b/string/test-strrchr.c
index 92e8ab1..64af621 100644
--- a/string/test-strrchr.c
+++ b/string/test-strrchr.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "strrchr"
 #include "test-string.h"
 
 typedef char *(*proto_t) (const char *, int);
diff --git a/string/test-strspn.c b/string/test-strspn.c
index 15cf492..ad7b845 100644
--- a/string/test-strspn.c
+++ b/string/test-strspn.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "strspn"
 #include "test-string.h"
 
 typedef size_t (*proto_t) (const char *, const char *);
diff --git a/string/test-strstr.c b/string/test-strstr.c
index c1da686..6116d70 100644
--- a/string/test-strstr.c
+++ b/string/test-strstr.c
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #define TEST_MAIN
+#define TEST_NAME "strstr"
 #include "test-string.h"
 
 
diff --git a/sysdeps/generic/libc-test.c b/sysdeps/generic/libc-test.c
new file mode 100644
index 0000000..672e1e4
--- /dev/null
+++ b/sysdeps/generic/libc-test.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 2010 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
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdlib.h>
+#include <libc-test.h>
+
+/* Return the NULL terminated array of functions.  */
+
+const struct libc_func_test *
+__libc_func (const char *name __attribute__ ((unused)))
+{
+  return NULL;
+}
diff --git a/sysdeps/x86_64/multiarch/libc-test.c b/sysdeps/x86_64/multiarch/libc-test.c
new file mode 100644
index 0000000..5975e0b
--- /dev/null
+++ b/sysdeps/x86_64/multiarch/libc-test.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 2010 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
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <libc-test.h>
+#include "init-arch.h"
+
+#if defined SHARED && !defined NOT_IN_libc
+extern void *__memcpy_sse2 (void *, const void *, size_t);
+extern void *__memcpy_ssse3 (void *, const void *, size_t);
+extern void *__memcpy_ssse3_back (void *, const void *, size_t);
+
+static const struct libc_func_test memcpy_list [] =
+{
+  { "__memcpy_ssse3_back", (void (*) (void)) __memcpy_ssse3_back },
+  { "__memcpy_ssse3", (void (*) (void)) __memcpy_ssse3 },
+  { "__memcpy_sse2", (void (*) (void)) __memcpy_sse2 },
+  { NULL, NULL },
+};
+
+static const struct libc_func_test *
+find_memcpy (void)
+{
+  return memcpy_list + (HAS_SSSE3 ? 0 : 2);
+}
+#else
+static const struct libc_func_test *
+find_memcpy (void)
+{
+  return NULL;
+}
+#endif
+
+const struct libc_func_test *
+__libc_func (const char *name)
+{
+  if (strcmp (name, "memcpy") == 0)
+    return find_memcpy ();
+
+  return NULL;
+}
diff --git a/sysdeps/x86_64/multiarch/memcpy.S b/sysdeps/x86_64/multiarch/memcpy.S
index 8e9fb19..a45ca9f 100644
--- a/sysdeps/x86_64/multiarch/memcpy.S
+++ b/sysdeps/x86_64/multiarch/memcpy.S
@@ -44,6 +44,8 @@ END(memcpy)
 # undef ENTRY
 # define ENTRY(name) \
 	.type __memcpy_sse2, @function; \
+	.globl __memcpy_sse2; \
+	.hidden __memcpy_sse2; \
 	.p2align 4; \
 	__memcpy_sse2: cfi_startproc; \
 	CALL_MCOUNT


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]