This is the mail archive of the glibc-cvs@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]

GNU C Library master sources branch hjl/pie/static created. glibc-2.25-795-g1325c9e


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, hjl/pie/static has been created
        at  1325c9e854e0abdedbc7629a939764857fcb921c (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=1325c9e854e0abdedbc7629a939764857fcb921c

commit 1325c9e854e0abdedbc7629a939764857fcb921c
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jul 19 14:32:42 2017 -0700

    Add _startup_sbrk and _startup_fatal

diff --git a/csu/libc-tls.c b/csu/libc-tls.c
index 0467450..4ae44d0 100644
--- a/csu/libc-tls.c
+++ b/csu/libc-tls.c
@@ -16,11 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <unistd.h>
+#include <stdio.h>
+#include <startup.h>
 #include <errno.h>
 #include <ldsodefs.h>
 #include <tls.h>
-#include <unistd.h>
-#include <stdio.h>
 #include <sys/param.h>
 
 
@@ -144,11 +145,11 @@ __libc_setup_tls (void)
      _dl_allocate_tls_storage (in elf/dl-tls.c) does using __libc_memalign
      and dl_tls_static_align.  */
   tcb_offset = roundup (memsz + GL(dl_tls_static_size), max_align);
-  tlsblock = __sbrk (tcb_offset + TLS_INIT_TCB_SIZE + max_align);
+  tlsblock = _startup_sbrk (tcb_offset + TLS_INIT_TCB_SIZE + max_align);
 #elif TLS_DTV_AT_TP
   tcb_offset = roundup (TLS_INIT_TCB_SIZE, align ?: 1);
-  tlsblock = __sbrk (tcb_offset + memsz + max_align
-		     + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+  tlsblock = _startup_sbrk (tcb_offset + memsz + max_align
+			    + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
   tlsblock += TLS_PRE_TCB_SIZE;
 #else
   /* In case a model with a different layout for the TCB and DTV
@@ -193,7 +194,7 @@ __libc_setup_tls (void)
 # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
 #endif
   if (__builtin_expect (lossage != NULL, 0))
-    __libc_fatal (lossage);
+    _startup_fatal (lossage);
 
   /* Update the executable's link map with enough information to make
      the TLS routines happy.  */
diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index 231fb8c..23c89b2 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -18,9 +18,11 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <unistd.h>
+#include <stdio.h>
+#include <startup.h>
 #include <stdint.h>
 #include <stdbool.h>
-#include <unistd.h>
 #include <stdlib.h>
 #include <sysdep.h>
 #include <fcntl.h>
@@ -42,7 +44,9 @@ tunables_strdup (const char *in)
   size_t i = 0;
 
   while (in[i++] != '\0');
-  char *out = __sbrk (i);
+
+  /* Can't use __sbrk before __libc_setup_tls is called.  */
+  char *out = _startup_sbrk (i);
 
   /* FIXME: In reality if the allocation fails, __sbrk will crash attempting to
      set the thread-local errno since the TCB has not yet been set up.  This
diff --git a/sysdeps/generic/startup.h b/sysdeps/generic/startup.h
new file mode 100644
index 0000000..aa63b31
--- /dev/null
+++ b/sysdeps/generic/startup.h
@@ -0,0 +1,30 @@
+/* Generic definitions of functions used by static libc main startup.
+   Copyright (C) 2017 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+static inline void *
+_startup_sbrk (intptr_t __delta)
+{
+  return __sbrk (__delta);
+}
+
+__attribute__ ((__noreturn__))
+static inline void
+_startup_fatal (const char *__message)
+{
+  __libc_fatal (__message);
+}
diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile
index 4080b8c..0ec6c21 100644
--- a/sysdeps/unix/sysv/linux/i386/Makefile
+++ b/sysdeps/unix/sysv/linux/i386/Makefile
@@ -31,6 +31,9 @@ sysdep_routines += divdi3
 shared-only-routines += divdi3
 CPPFLAGS-divdi3.c = -Din_divdi3_c
 endif
+ifeq (yes,$(enable-static-pie))
+sysdep_routines += startup_sbrk
+endif
 endif
 
 ifeq ($(subdir),nptl)
diff --git a/sysdeps/unix/sysv/linux/i386/startup.h b/sysdeps/unix/sysv/linux/i386/startup.h
new file mode 100644
index 0000000..d5af723
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/startup.h
@@ -0,0 +1,38 @@
+/* Linux/i386 definitions of functions used by static libc main startup.
+   Copyright (C) 2017 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#if ENABLE_STATIC_PIE && !defined SHARED
+# include <abort-instr.h>
+
+/* Can't use "call *%gs:SYSINFO_OFFSET" during statup in static PIE.  */
+# define I386_USE_SYSENTER 0
+
+extern void * _startup_sbrk (intptr_t) attribute_hidden;
+
+__attribute__ ((__noreturn__))
+static inline void
+_startup_fatal (const char *__message __attribute__ ((unused)))
+{
+  /* This is only called very early during startup in static PIE.
+     FIXME: How can it be improved?  */
+  ABORT_INSTRUCTION;
+  __builtin_unreachable ();
+}
+#else
+# include_next <startup.h>
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/startup_sbrk.c b/sysdeps/unix/sysv/linux/i386/startup_sbrk.c
new file mode 100644
index 0000000..9a2d317
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/startup_sbrk.c
@@ -0,0 +1,70 @@
+/* Linux/i386 definitions of _startup_sbrk.
+   Copyright (C) 2017 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef SHARED
+
+# include <unistd.h>
+# include <startup.h>
+# include <errno.h>
+# include <sysdep.h>
+
+/* Defined in brk.c.  */
+extern void *__curbrk attribute_hidden;
+
+static int
+startup_brk (void *addr)
+{
+  INTERNAL_SYSCALL_DECL (err);
+  void *newbrk = (void *) INTERNAL_SYSCALL_CALL (brk, err, addr);
+  __curbrk = newbrk;
+  if (newbrk < addr)
+    _startup_fatal (NULL);
+  return 0;
+}
+
+/* Extend the process's data space by INCREMENT.  If INCREMENT is negative,
+   shrink data space by - INCREMENT.  Return start of new space allocated,
+   or call _startup_fatal for errors.  */
+
+void *
+_startup_sbrk (intptr_t increment)
+{
+  void *oldbrk;
+
+  /* Update __curbrk from the kernel's brk value.  That way two separate
+     instances of __brk and __sbrk can share the heap, returning
+     interleaved pieces of it.  */
+  if (__curbrk == NULL)
+    if (startup_brk (0) < 0)		/* Initialize the break.  */
+      _startup_fatal (NULL);
+
+  if (increment == 0)
+    return __curbrk;
+
+  oldbrk = __curbrk;
+  if (increment > 0
+      ? ((uintptr_t) oldbrk + (uintptr_t) increment < (uintptr_t) oldbrk)
+      : ((uintptr_t) oldbrk < (uintptr_t) -increment))
+    _startup_fatal (NULL);
+
+  if (startup_brk (oldbrk + increment) < 0)
+    _startup_fatal (NULL);
+
+  return oldbrk;
+}
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=0dbc8246f4629ba08b3a815260db833d625d59d0

commit 0dbc8246f4629ba08b3a815260db833d625d59d0
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jul 19 09:32:45 2017 -0700

    i386: Define I386_USE_SYSENTER to 0 or 1 and check PIC
    
    Define I386_USE_SYSENTER to 0 or 1 so that special versions of syscalls
    with "int $0x80" can be provided for static PIE during start up.  Also
    check PIC instead SHARED for PIC version of syscall macros.
    
    	* sysdeps/unix/sysv/linux/i386/sysdep.h (I386_USE_SYSENTER):
    	Define to I386_USE_SYSENTER to 0 or 1 if not defined.
    	(ENTER_KERNEL): Check if I386_USE_SYSENTER is 1 and check PIC.
    	(INTERNAL_SYSCALL_MAIN_INLINE): Likewise.
    	(INTERNAL_SYSCALL_NCS): Likewise.
    	(LOADARGS_1): Likewise.
    	(LOADARGS_5): Likewise.
    	(RESTOREARGS_1): Likewise.
    	(RESTOREARGS_5): Likewise.

diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 449b23e..c455c9b 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -34,11 +34,13 @@
 #undef SYS_ify
 #define SYS_ify(syscall_name)	__NR_##syscall_name
 
-#if defined USE_DL_SYSINFO \
-    && (IS_IN (libc) || IS_IN (libpthread))
-# define I386_USE_SYSENTER	1
-#else
-# undef I386_USE_SYSENTER
+#ifndef I386_USE_SYSENTER
+# if defined USE_DL_SYSINFO \
+     && (IS_IN (libc) || IS_IN (libpthread))
+#  define I386_USE_SYSENTER	1
+# else
+#  define I386_USE_SYSENTER	0
+# endif
 #endif
 
 /* Since GCC 5 and above can properly spill %ebx with PIC when needed,
@@ -110,8 +112,8 @@
 
 /* The original calling convention for system calls on Linux/i386 is
    to use int $0x80.  */
-#ifdef I386_USE_SYSENTER
-# ifdef SHARED
+#if I386_USE_SYSENTER
+# ifdef PIC
 #  define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
 # else
 #  define ENTER_KERNEL call *_dl_sysinfo
@@ -357,9 +359,9 @@ struct libc_do_syscall_args
     register unsigned int resultvar;					      \
     INTERNAL_SYSCALL_MAIN_##nr (name, err, args);			      \
     (int) resultvar; })
-#ifdef I386_USE_SYSENTER
+#if I386_USE_SYSENTER
 # ifdef OPTIMIZE_FOR_GCC_5
-#  ifdef SHARED
+#  ifdef PIC
 #   define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
     LOADREGS_##nr(args)							\
     asm volatile (							\
@@ -395,7 +397,7 @@ struct libc_do_syscall_args
     (int) resultvar; })
 #  endif
 # else /* GCC 5  */
-#  ifdef SHARED
+#  ifdef PIC
 #   define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
     EXTRAVAR_##nr							      \
     asm volatile (							      \
@@ -494,7 +496,7 @@ struct libc_do_syscall_args
 
 #define LOADARGS_0
 #ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if I386_USE_SYSENTER && defined PIC
 #  define LOADARGS_1 \
     "bpushl .L__X'%k3, %k3\n\t"
 #  define LOADARGS_5 \
@@ -521,7 +523,7 @@ struct libc_do_syscall_args
 
 #define RESTOREARGS_0
 #ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if I386_USE_SYSENTER && defined PIC
 #  define RESTOREARGS_1 \
     "bpopl .L__X'%k3, %k3\n\t"
 #  define RESTOREARGS_5 \

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=9497821aee010848dbc0290aeb2ffca7828e3248

commit 9497821aee010848dbc0290aeb2ffca7828e3248
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Jul 18 15:46:40 2017 -0700

    i386: Check PIC in i386 multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/memcmp-sse4.S b/sysdeps/i386/i686/multiarch/memcmp-sse4.S
index 2aa1304..f524ec9 100644
--- a/sysdeps/i386/i686/multiarch/memcmp-sse4.S
+++ b/sysdeps/i386/i686/multiarch/memcmp-sse4.S
@@ -43,7 +43,7 @@
 # define RETURN	POP (%ebx); ret; CFI_PUSH (%ebx)
 
 
-# ifdef SHARED
+# ifdef PIC
 #  define JMPTBL(I, B)	I - B
 
 /* Load an entry in a jump table into EBX and branch to it.  TABLE is a
diff --git a/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S b/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S
index fd3f499..c57f725 100644
--- a/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S
+++ b/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S
@@ -157,7 +157,7 @@ L(mm_len_128_or_more_backward):
 # ifdef SHARED_CACHE_SIZE_HALF
 	cmp	$SHARED_CACHE_SIZE_HALF, %edi
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	PUSH (%ebx)
 	SETUP_PIC_REG (bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
@@ -351,7 +351,7 @@ L(mm_len_128_or_more_forward):
 # ifdef SHARED_CACHE_SIZE_HALF
 	cmp	$SHARED_CACHE_SIZE_HALF, %edi
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	PUSH (%ebx)
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
@@ -469,7 +469,7 @@ L(forward):
 # ifdef SHARED_CACHE_SIZE_HALF
 	cmp	$SHARED_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_shared_cache_size_half@GOTOFF(%ebx), %ecx
diff --git a/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S b/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S
index 46d6597..42105c3 100644
--- a/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S
+++ b/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S
@@ -52,7 +52,7 @@
 #define PUSH(REG)	pushl REG; CFI_PUSH (REG)
 #define POP(REG)	popl REG; CFI_POP (REG)
 
-#ifdef SHARED
+#ifdef PIC
 # define PARMS		8		/* Preserve EBX.  */
 # define ENTRANCE	PUSH (%ebx);
 # define RETURN_END	POP (%ebx); ret
@@ -160,7 +160,7 @@ L(48bytesormore):
 #ifdef SHARED_CACHE_SIZE_HALF
 	cmp	$SHARED_CACHE_SIZE_HALF, %ecx
 #else
-# ifdef SHARED
+# ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_shared_cache_size_half@GOTOFF(%ebx), %ecx
@@ -230,7 +230,7 @@ L(shl_0_gobble):
 #ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 #else
-# ifdef SHARED
+# ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	mov	__x86_data_cache_size_half@GOTOFF(%ebx), %edi
diff --git a/sysdeps/i386/i686/multiarch/memcpy-ssse3.S b/sysdeps/i386/i686/multiarch/memcpy-ssse3.S
index 8b33153..ce5d085 100644
--- a/sysdeps/i386/i686/multiarch/memcpy-ssse3.S
+++ b/sysdeps/i386/i686/multiarch/memcpy-ssse3.S
@@ -51,7 +51,7 @@
 # define PUSH(REG)	pushl REG; CFI_PUSH (REG)
 # define POP(REG)	popl REG; CFI_POP (REG)
 
-# ifdef SHARED
+# ifdef PIC
 #  define PARMS		8		/* Preserve EBX.  */
 #  define ENTRANCE	PUSH (%ebx);
 #  define RETURN_END	POP (%ebx); ret
@@ -157,7 +157,7 @@ L(48bytesormore):
 # ifdef SHARED_CACHE_SIZE_HALF
 	cmp	$SHARED_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_shared_cache_size_half@GOTOFF(%ebx), %ecx
@@ -231,7 +231,7 @@ L(shl_0_gobble):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -390,7 +390,7 @@ L(shl_1):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -494,7 +494,7 @@ L(shl_2):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -598,7 +598,7 @@ L(shl_3):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -704,7 +704,7 @@ L(shl_4):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -810,7 +810,7 @@ L(shl_5):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -916,7 +916,7 @@ L(shl_6):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -1022,7 +1022,7 @@ L(shl_7):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -1126,7 +1126,7 @@ L(shl_8):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -1230,7 +1230,7 @@ L(shl_9):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -1335,7 +1335,7 @@ L(shl_10):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -1440,7 +1440,7 @@ L(shl_11):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -1545,7 +1545,7 @@ L(shl_12):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -1650,7 +1650,7 @@ L(shl_13):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -1755,7 +1755,7 @@ L(shl_14):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
@@ -1860,7 +1860,7 @@ L(shl_15):
 # ifdef DATA_CACHE_SIZE_HALF
 	cmp	$DATA_CACHE_SIZE_HALF, %ecx
 # else
-#  ifdef SHARED
+#  ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	cmp	__x86_data_cache_size_half@GOTOFF(%ebx), %ecx
diff --git a/sysdeps/i386/i686/multiarch/memset-sse2-rep.S b/sysdeps/i386/i686/multiarch/memset-sse2-rep.S
index 3221077..e70a4e4 100644
--- a/sysdeps/i386/i686/multiarch/memset-sse2-rep.S
+++ b/sysdeps/i386/i686/multiarch/memset-sse2-rep.S
@@ -44,7 +44,7 @@
 # define SETRTNVAL	movl DEST(%esp), %eax
 #endif
 
-#ifdef SHARED
+#ifdef PIC
 # define ENTRANCE	PUSH (%ebx);
 # define RETURN_END	POP (%ebx); ret
 # define RETURN		RETURN_END; CFI_PUSH (%ebx)
@@ -262,7 +262,7 @@ L(128bytesormore):
 	PUSH (%ebx)
 	mov	$DATA_CACHE_SIZE, %ebx
 #else
-# ifdef SHARED
+# ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	mov	__x86_data_cache_size@GOTOFF(%ebx), %ebx
@@ -274,7 +274,7 @@ L(128bytesormore):
 	mov	%ebx, %edi
 	shr	$4, %ebx
 	sub	%ebx, %edi
-#if defined DATA_CACHE_SIZE || !defined SHARED
+#if defined DATA_CACHE_SIZE || !defined PIC
 	POP (%ebx)
 #endif
 /*
diff --git a/sysdeps/i386/i686/multiarch/memset-sse2.S b/sysdeps/i386/i686/multiarch/memset-sse2.S
index d7b8be9..cf3a84e 100644
--- a/sysdeps/i386/i686/multiarch/memset-sse2.S
+++ b/sysdeps/i386/i686/multiarch/memset-sse2.S
@@ -44,7 +44,7 @@
 # define SETRTNVAL	movl DEST(%esp), %eax
 #endif
 
-#ifdef SHARED
+#ifdef PIC
 # define ENTRANCE	PUSH (%ebx);
 # define RETURN_END	POP (%ebx); ret
 # define RETURN		RETURN_END; CFI_PUSH (%ebx)
@@ -261,7 +261,7 @@ L(128bytesormore):
 	PUSH (%ebx)
 	mov	$SHARED_CACHE_SIZE, %ebx
 #else
-# ifdef SHARED
+# ifdef PIC
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 	mov	__x86_shared_cache_size@GOTOFF(%ebx), %ebx
@@ -279,7 +279,7 @@ L(128bytesormore):
 # define RESTORE_EBX_STATE CFI_PUSH (%ebx)
 	cmp	$DATA_CACHE_SIZE, %ecx
 #else
-# ifdef SHARED
+# ifdef PIC
 #  define RESTORE_EBX_STATE
 	SETUP_PIC_REG(bx)
 	add	$_GLOBAL_OFFSET_TABLE_, %ebx
@@ -380,7 +380,7 @@ L(128bytesormore_nt):
 	jae	L(128bytesormore_nt)
 	sfence
 L(shared_cache_loop_end):
-#if defined DATA_CACHE_SIZE || !defined SHARED
+#if defined DATA_CACHE_SIZE || !defined PIC
 	POP (%ebx)
 #endif
 	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))
diff --git a/sysdeps/i386/i686/multiarch/strcat-sse2.S b/sysdeps/i386/i686/multiarch/strcat-sse2.S
index 6359c73..ca3416f 100644
--- a/sysdeps/i386/i686/multiarch/strcat-sse2.S
+++ b/sysdeps/i386/i686/multiarch/strcat-sse2.S
@@ -34,7 +34,7 @@
 # define PUSH(REG) pushl REG; CFI_PUSH (REG)
 # define POP(REG) popl REG; CFI_POP (REG)
 
-# ifdef SHARED
+# ifdef PIC
 #  define JMPTBL(I, B) I - B
 
 /* Load an entry in a jump table into ECX and branch to it.  TABLE is a
diff --git a/sysdeps/i386/i686/multiarch/strcpy-sse2.S b/sysdeps/i386/i686/multiarch/strcpy-sse2.S
index ed627a5..a9d5f5b 100644
--- a/sysdeps/i386/i686/multiarch/strcpy-sse2.S
+++ b/sysdeps/i386/i686/multiarch/strcpy-sse2.S
@@ -48,7 +48,7 @@
 #  define RETURN  POP(%edi); POP(%esi); POP(%ebx); ret;          \
 	CFI_PUSH(%ebx); CFI_PUSH(%esi); CFI_PUSH(%edi);
 
-# ifdef SHARED
+# ifdef PIC
 #  define JMPTBL(I, B)	I - B
 
 /* Load an entry in a jump table into ECX and branch to it. TABLE is a

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=1c673e7c69f1f436bf952906e3bee3192e7fe9a4

commit 1c673e7c69f1f436bf952906e3bee3192e7fe9a4
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Jul 18 15:45:46 2017 -0700

    i386: Check PIC instead of SHARED in start.S
    
    Support static PIE.  Avoid relocation in static PIE since _start is
    called before it is relocated.

diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S
index ccb1e2b..3372186 100644
--- a/sysdeps/i386/start.S
+++ b/sysdeps/i386/start.S
@@ -81,7 +81,7 @@ _start:
 	pushl %edx		/* Push address of the shared library
 				   termination function.  */
 
-#ifdef SHARED
+#ifdef PIC
 	/* Load PIC register.  */
 	call 1f
 	addl $_GLOBAL_OFFSET_TABLE_, %ebx
@@ -95,7 +95,14 @@ _start:
 	pushl %ecx		/* Push second argument: argv.  */
 	pushl %esi		/* Push first argument: argc.  */
 
+# ifdef SHARED
 	pushl main@GOT(%ebx)
+# else
+	/* Avoid relocation in static PIE since _start is called before
+	   it is relocated.  */
+	lea main@GOTOFF(%ebx), %eax
+	pushl %eax
+# endif
 
 	/* Call the user's main function, and exit with its value.
 	   But let the libc call main.    */
@@ -117,7 +124,7 @@ _start:
 
 	hlt			/* Crash if somehow `exit' does return.  */
 
-#ifdef SHARED
+#ifdef PIC
 1:	movl	(%esp), %ebx
 	ret
 #endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=840845842afbd8502e835fdbabcc94d3efd066c2

commit 840845842afbd8502e835fdbabcc94d3efd066c2
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Jul 18 10:42:48 2017 -0700

    Use hidden visibility for ENABLE_STATIC_PIE

diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 3310e3a..c3f189b 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -355,7 +355,8 @@ for linking")
   strong_alias(real, name)
 #endif
 
-#if defined SHARED || defined LIBC_NONSHARED
+#if defined SHARED || defined LIBC_NONSHARED \
+    || (ENABLE_STATIC_PIE && IS_IN (libc))
 # define attribute_hidden __attribute__ ((visibility ("hidden")))
 #else
 # define attribute_hidden

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8a569f52c8bb7f8a7e8d62b9e477a1161026a7b0

commit 8a569f52c8bb7f8a7e8d62b9e477a1161026a7b0
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Jul 17 13:53:52 2017 -0700

    Add _dl_relocate_static_pie

diff --git a/csu/libc-start.c b/csu/libc-start.c
index 6720617..f2874b8 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -143,6 +143,8 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
   __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up;
 
 #ifndef SHARED
+  _dl_relocate_static_pie ();
+
   char **ev = &argv[argc + 1];
 
   __environ = ev;
diff --git a/csu/libc-tls.c b/csu/libc-tls.c
index 3c897bf..0467450 100644
--- a/csu/libc-tls.c
+++ b/csu/libc-tls.c
@@ -113,6 +113,8 @@ __libc_setup_tls (void)
   size_t tcb_offset;
   const ElfW(Phdr) *phdr;
 
+  struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+
   /* Look through the TLS segment if there is any.  */
   if (_dl_phdr != NULL)
     for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr)
@@ -121,7 +123,7 @@ __libc_setup_tls (void)
 	  /* Remember the values we need.  */
 	  memsz = phdr->p_memsz;
 	  filesz = phdr->p_filesz;
-	  initimage = (void *) phdr->p_vaddr;
+	  initimage = (void *) phdr->p_vaddr + main_map->l_addr;
 	  align = phdr->p_align;
 	  if (phdr->p_align > max_align)
 	    max_align = phdr->p_align;
@@ -162,8 +164,6 @@ __libc_setup_tls (void)
   _dl_static_dtv[0].counter = (sizeof (_dl_static_dtv) / sizeof (_dl_static_dtv[0])) - 2;
   // _dl_static_dtv[1].counter = 0;		would be needed if not already done
 
-  struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
-
   /* Initialize the TLS block.  */
 #if TLS_TCB_AT_TP
   _dl_static_dtv[2].pointer.val = ((char *) tlsblock + tcb_offset
diff --git a/elf/dl-support.c b/elf/dl-support.c
index c22be85..29dd6eb 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -26,7 +26,11 @@
 #include <sys/param.h>
 #include <stdint.h>
 #include <ldsodefs.h>
-#include <dl-machine.h>
+#if ENABLE_STATIC_PIE
+# include "dynamic-link.h"
+#else
+# include <dl-machine.h>
+#endif
 #include <libc-lock.h>
 #include <dl-cache.h>
 #include <dl-librecon.h>
@@ -200,7 +204,9 @@ const ElfW(Ehdr) *_dl_sysinfo_dso;
 
 struct link_map *_dl_sysinfo_map;
 
-# include "get-dynamic-info.h"
+# if !ENABLE_STATIC_PIE
+#  include "get-dynamic-info.h"
+# endif
 #endif
 #include "setup-vdso.h"
 
@@ -304,6 +310,35 @@ _dl_aux_init (ElfW(auxv_t) *av)
 }
 #endif
 
+#if ENABLE_STATIC_PIE
+/* Relocate static executable with PIE.  */
+
+void
+_dl_relocate_static_pie (void)
+{
+# define STATIC_PIE_BOOTSTRAP
+# define RESOLVE_MAP(sym, version, flags) (&_dl_main_map)
+# include "dynamic-link.h"
+
+  /* Figure out the run-time load addres of static PIE.  */
+  _dl_main_map.l_addr = elf_machine_load_address ();
+
+  /* Read our own dynamic section and fill in the info array.  */
+  _dl_main_map.l_ld = ((void *) _dl_main_map.l_addr
+		       + elf_machine_dynamic ());
+  elf_get_dynamic_info (&_dl_main_map, NULL);
+
+# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
+  ELF_MACHINE_BEFORE_RTLD_RELOC (_dl_main_map.l_info);
+# endif
+
+  /* Relocate ourselves so we can do normal function calls and
+     data access using the global offset table.  */
+  ELF_DYNAMIC_RELOCATE (&_dl_main_map, 0, 0, 0);
+  _dl_main_map.l_relocated = 1;
+}
+#endif
+
 
 void
 internal_function
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 60f2d91..d3935f7 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -95,7 +95,7 @@ elf_machine_lazy_rel (struct link_map *map,
 
 #ifdef RESOLVE_MAP
 
-# ifdef RTLD_BOOTSTRAP
+# if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
 #  define ELF_DURING_STARTUP (1)
 # else
 #  define ELF_DURING_STARTUP (0)
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index 7525c3a..eb26d23 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -38,7 +38,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
   typedef Elf64_Xword d_tag_utype;
 #endif
 
-#ifndef RTLD_BOOTSTRAP
+#if !defined RTLD_BOOTSTRAP && !defined STATIC_PIE_BOOTSTRAP
   if (dyn == NULL)
     return;
 #endif
@@ -139,9 +139,11 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
   /* Only the bind now flags are allowed.  */
   assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
 	  || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
+  /* Flags must not be set for ld.so.  */
   assert (info[DT_FLAGS] == NULL
 	  || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
-  /* Flags must not be set for ld.so.  */
+#endif
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
   assert (info[DT_RUNPATH] == NULL);
   assert (info[DT_RPATH] == NULL);
 #else
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 4508365..17f760b 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1006,6 +1006,13 @@ extern void _dl_determine_tlsoffset (void) internal_function attribute_hidden;
    stack protector, among other things).  */
 void __libc_setup_tls (void);
 
+# if ENABLE_STATIC_PIE
+/* Relocate static executable with PIE.  */
+void _dl_relocate_static_pie (void) attribute_hidden;
+# else
+#  define _dl_relocate_static_pie()
+# endif
+
 /* Initialization of libpthread for statically linked applications.
    If libpthread is not linked in, this is an empty function.  */
 void __pthread_initialize_minimal (void) weak_function;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=dacfa6dd23732f796474e295bc660aeec3741c7c

commit dacfa6dd23732f796474e295bc660aeec3741c7c
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Jul 17 08:54:40 2017 -0700

    Define pie-default/default-pie-ldflag for --enable-static-pie
    
    1. Add $(pie-default) to CFLAGS-.o and CFLAGS-.op.
    2. Add $(default-pie-ldflag) to +link-static-before-libc.
    3. Define +prectorT/+postctorT to $(+prectorS)/$(+postctorS).

diff --git a/Makeconfig b/Makeconfig
index 80aed2a..3af2abc 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -386,6 +386,16 @@ LDFLAGS.so += $(hashstyle-LDFLAGS)
 LDFLAGS-rtld += $(hashstyle-LDFLAGS)
 endif
 
+ifeq (yes,$(enable-static-pie))
+pic-default = -DPIC
+pie-default = -fPIE
+ifeq (yes,$(have-static-pie))
+default-pie-ldflag = -static-pie
+else
+default-pie-ldflag = -pie -Wl,--no-dynamic-linker,--eh-frame-hdr,-z,text
+endif
+endif
+
 # If lazy relocations are disabled, add the -z now flag.  Use
 # LDFLAGS-lib.so instead of LDFLAGS.so, to avoid adding the flag to
 # test modules.
@@ -435,6 +445,7 @@ endif
 # Command for statically linking programs with the C library.
 ifndef +link-static
 +link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \
+	      $(default-pie-ldflag) \
 	      $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F))  \
 	      $(addprefix $(csu-objpfx),$(static-start-installed-name)) \
 	      $(+preinit) $(+prectorT) \
@@ -651,8 +662,13 @@ endif
 +prectorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginS.o`
 +postctorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtendS.o`
 # Variants of the two previous definitions for statically linking programs.
+ifeq (yes,$(enable-static-pie))
++prectorT = $(+prectorS)
++postctorT = $(+postctorS)
+else
 +prectorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginT.o`
 +postctorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o`
+endif
 csu-objpfx = $(common-objpfx)csu/
 elf-objpfx = $(common-objpfx)elf/
 
@@ -973,7 +989,7 @@ libtypes = $(foreach o,$(object-suffixes-for-libc),$(libtype$o))
 all-object-suffixes := .o .os .oS
 object-suffixes :=
 CPPFLAGS-.o = $(pic-default)
-CFLAGS-.o = $(filter %frame-pointer,$(+cflags))
+CFLAGS-.o = $(filter %frame-pointer,$(+cflags)) $(pie-default)
 libtype.o := lib%.a
 object-suffixes += .o
 ifeq (yes,$(build-shared))
@@ -998,7 +1014,7 @@ ifeq (yes,$(build-profile))
 all-object-suffixes += .op
 object-suffixes += .op
 CPPFLAGS-.op = -DPROF $(pic-default)
-CFLAGS-.op = -pg
+CFLAGS-.op = -pg $(pie-default)
 libtype.op = lib%_p.a
 endif
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a1a942cdb49f0841e1fcc5c7e6014b2cebae2613

commit a1a942cdb49f0841e1fcc5c7e6014b2cebae2613
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Jul 18 05:58:21 2017 -0700

    x86-64: Check if linker supports static PIE
    
    Need the linker with fix for:
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=21782
    
    Binutils 2.29 is OK.

diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure
index efef46b..7983c96 100644
--- a/sysdeps/x86_64/configure
+++ b/sysdeps/x86_64/configure
@@ -85,6 +85,43 @@ if test x"$build_mathvec" = xnotset; then
   build_mathvec=yes
 fi
 
+if test "$static_pie" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker static PIE support" >&5
+$as_echo_n "checking for linker static PIE support... " >&6; }
+if ${libc_cv_ld_static_pie+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.s <<\EOF
+	.text
+	.global _start
+	.weak foo
+_start:
+	leaq	foo(%rip), %rax
+EOF
+  if test "$libc_cv_static_pie" = yes; then
+    libc_cv_static_pie_option="-static-pie"
+  else
+    libc_cv_static_pie_option="-static -pie"
+  fi
+  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_static_pie_option conftest.s 1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    libc_cv_ld_static_pie=yes
+  else
+    libc_cv_ld_static_pie=no
+  fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ld_static_pie" >&5
+$as_echo "$libc_cv_ld_static_pie" >&6; }
+  if test "$libc_cv_ld_static_pie" != yes; then
+    as_fn_error $? "linker support for static PIE needed" "$LINENO" 5
+  fi
+fi
+
 $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
 
 
diff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac
index fa86e95..4de1983 100644
--- a/sysdeps/x86_64/configure.ac
+++ b/sysdeps/x86_64/configure.ac
@@ -44,6 +44,32 @@ if test x"$build_mathvec" = xnotset; then
   build_mathvec=yes
 fi
 
+dnl Check if linker supports static PIE.
+if test "$static_pie" = yes; then
+  AC_CACHE_CHECK(for linker static PIE support, libc_cv_ld_static_pie, [dnl
+cat > conftest.s <<\EOF
+	.text
+	.global _start
+	.weak foo
+_start:
+	leaq	foo(%rip), %rax
+EOF
+  if test "$libc_cv_static_pie" = yes; then
+    libc_cv_static_pie_option="-static-pie"
+  else
+    libc_cv_static_pie_option="-static -pie"
+  fi
+  if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_static_pie_option conftest.s 1>&AS_MESSAGE_LOG_FD); then
+    libc_cv_ld_static_pie=yes
+  else
+    libc_cv_ld_static_pie=no
+  fi
+rm -f conftest*])
+  if test "$libc_cv_ld_static_pie" != yes; then
+    AC_MSG_ERROR([linker support for static PIE needed])
+  fi
+fi
+
 dnl It is always possible to access static and hidden symbols in an
 dnl position independent way.
 AC_DEFINE(PI_STATIC_AND_HIDDEN)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a5cc4892a32f26d4d9b8d45b34987de19cc53120

commit a5cc4892a32f26d4d9b8d45b34987de19cc53120
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Jul 17 08:36:45 2017 -0700

    Add --enable-static-pie

diff --git a/config.h.in b/config.h.in
index 2241857..983405a 100644
--- a/config.h.in
+++ b/config.h.in
@@ -246,6 +246,9 @@
 /* Build glibc with tunables support.  */
 #define HAVE_TUNABLES 0
 
+/* Define if static PIE is enabled.  */
+#define ENABLE_STATIC_PIE 0
+
 /* Some compiler options may now allow to use ebp in __asm__ (used mainly
    in i386 6 argument syscall issue).  */
 #define CAN_USE_REGISTER_ASM_EBP 0
diff --git a/configure b/configure
index 5ac964d..edd4989 100755
--- a/configure
+++ b/configure
@@ -765,6 +765,7 @@ with_default_link
 enable_sanity_checks
 enable_shared
 enable_profile
+enable_static_pie
 enable_timezone_tools
 enable_hardcoded_path_in_tests
 enable_stackguard_randomization
@@ -1422,6 +1423,7 @@ Optional Features:
                           in special situations) [default=yes]
   --enable-shared         build shared library [default=yes if GNU ld]
   --enable-profile        build profiled library [default=no]
+  --enable-static-pie     build static executables as PIE [default=no]
   --disable-timezone-tools
                           do not install timezone tools [default=install]
   --enable-hardcoded-path-in-tests
@@ -3370,6 +3372,13 @@ else
   profile=no
 fi
 
+# Check whether --enable-static-pie was given.
+if test "${enable_static_pie+set}" = set; then :
+  enableval=$enable_static_pie; static_pie=$enableval
+else
+  static_pie=no
+fi
+
 # Check whether --enable-timezone-tools was given.
 if test "${enable_timezone_tools+set}" = set; then :
   enableval=$enable_timezone_tools; enable_timezone_tools=$enableval
@@ -6908,6 +6917,18 @@ fi
 $as_echo "$libc_cv_pie_default" >&6; }
 
 
+# The linker must support --no-dynamic-linker if --enable-static-pie is
+# used.
+if test "$static_pie" = yes; then
+  if test "$libc_cv_no_dynamic_linker" != yes; then
+    as_fn_error $? "linker support for --no-dynamic-linker needed" "$LINENO" 5
+  fi
+  $as_echo "#define ENABLE_STATIC_PIE 1" >>confdefs.h
+
+fi
+config_vars="$config_vars
+enable-static-pie = $static_pie"
+
 
 
 
diff --git a/configure.ac b/configure.ac
index fe842fb..f583cd3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -176,6 +176,11 @@ AC_ARG_ENABLE([profile],
 			     [build profiled library @<:@default=no@:>@]),
 	      [profile=$enableval],
 	      [profile=no])
+AC_ARG_ENABLE([static-pie],
+	      AC_HELP_STRING([--enable-static-pie],
+			     [build static executables as PIE @<:@default=no@:>@]),
+	      [static_pie=$enableval],
+	      [static_pie=no])
 AC_ARG_ENABLE([timezone-tools],
 	      AC_HELP_STRING([--disable-timezone-tools],
 			     [do not install timezone tools @<:@default=install@:>@]),
@@ -1954,6 +1959,16 @@ fi
 rm -f conftest.*])
 AC_SUBST(libc_cv_pie_default)
 
+# The linker must support --no-dynamic-linker if --enable-static-pie is
+# used.
+if test "$static_pie" = yes; then
+  if test "$libc_cv_no_dynamic_linker" != yes; then
+    AC_MSG_ERROR([linker support for --no-dynamic-linker needed])
+  fi
+  AC_DEFINE(ENABLE_STATIC_PIE)
+fi
+LIBC_CONFIG_VAR([enable-static-pie], [$static_pie])
+
 AC_SUBST(profile)
 AC_SUBST(static_nss)
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a08f2e06d0fd2c9d9f2520cf19b39f194b7d706b

commit a08f2e06d0fd2c9d9f2520cf19b39f194b7d706b
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Jul 21 05:07:19 2017 -0700

    Check if -static-pie works

diff --git a/configure b/configure
index 69363e8..5ac964d 100755
--- a/configure
+++ b/configure
@@ -5992,6 +5992,28 @@ $as_echo "$libc_linker_feature" >&6; }
 config_vars="$config_vars
 have-no-dynamic-linker = $libc_cv_no_dynamic_linker"
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -static-pie" >&5
+$as_echo_n "checking for -static-pie... " >&6; }
+if ${libc_cv_static_pie+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if { ac_try='${CC-cc} -static-pie -xc /dev/null -S -o /dev/null'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  libc_cv_static_pie=yes
+else
+  libc_cv_static_pie=no
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie" >&5
+$as_echo "$libc_cv_static_pie" >&6; }
+config_vars="$config_vars
+have-static-pie = $libc_cv_static_pie"
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fpie" >&5
 $as_echo_n "checking for -fpie... " >&6; }
 if ${libc_cv_fpie+:} false; then :
diff --git a/configure.ac b/configure.ac
index 53fdd6a..fe842fb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1445,6 +1445,13 @@ LIBC_LINKER_FEATURE([--no-dynamic-linker],
 		    [libc_cv_no_dynamic_linker=no])
 LIBC_CONFIG_VAR([have-no-dynamic-linker], [$libc_cv_no_dynamic_linker])
 
+AC_CACHE_CHECK(for -static-pie, libc_cv_static_pie, [dnl
+LIBC_TRY_CC_OPTION([-static-pie],
+		   [libc_cv_static_pie=yes],
+		   [libc_cv_static_pie=no])
+])
+LIBC_CONFIG_VAR([have-static-pie], [$libc_cv_static_pie])
+
 AC_CACHE_CHECK(for -fpie, libc_cv_fpie, [dnl
 LIBC_TRY_CC_OPTION([-fpie], [libc_cv_fpie=yes], [libc_cv_fpie=no])
 ])

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e25269f0b1cc96d04238f678518fa97041293fac

commit e25269f0b1cc96d04238f678518fa97041293fac
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Jul 17 08:17:32 2017 -0700

    Check if linker supports --no-dynamic-linker

diff --git a/configure b/configure
index d8e1c50..69363e8 100755
--- a/configure
+++ b/configure
@@ -5958,6 +5958,40 @@ fi
 $as_echo "$libc_linker_feature" >&6; }
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports --no-dynamic-linker" >&5
+$as_echo_n "checking for linker that supports --no-dynamic-linker... " >&6; }
+libc_linker_feature=no
+if test x"$gnu_ld" = x"yes"; then
+  libc_linker_check=`$LD -v --help 2>/dev/null | grep "\--no-dynamic-linker"`
+  if test -n "$libc_linker_check"; then
+    cat > conftest.c <<EOF
+int _start (void) { return 42; }
+EOF
+    if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
+				-Wl,--no-dynamic-linker -nostdlib -nostartfiles
+				-fPIC -shared -o conftest.so conftest.c
+				1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+      libc_linker_feature=yes
+    fi
+    rm -f conftest*
+  fi
+fi
+if test $libc_linker_feature = yes; then
+  libc_cv_no_dynamic_linker=yes
+else
+  libc_cv_no_dynamic_linker=no
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5
+$as_echo "$libc_linker_feature" >&6; }
+config_vars="$config_vars
+have-no-dynamic-linker = $libc_cv_no_dynamic_linker"
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fpie" >&5
 $as_echo_n "checking for -fpie... " >&6; }
 if ${libc_cv_fpie+:} false; then :
diff --git a/configure.ac b/configure.ac
index 77456aa..53fdd6a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1439,6 +1439,12 @@ LIBC_LINKER_FEATURE([-z execstack], [-Wl,-z,execstack],
 		    [libc_cv_z_execstack=yes], [libc_cv_z_execstack=no])
 AC_SUBST(libc_cv_z_execstack)
 
+LIBC_LINKER_FEATURE([--no-dynamic-linker],
+		    [-Wl,--no-dynamic-linker],
+		    [libc_cv_no_dynamic_linker=yes],
+		    [libc_cv_no_dynamic_linker=no])
+LIBC_CONFIG_VAR([have-no-dynamic-linker], [$libc_cv_no_dynamic_linker])
+
 AC_CACHE_CHECK(for -fpie, libc_cv_fpie, [dnl
 LIBC_TRY_CC_OPTION([-fpie], [libc_cv_fpie=yes], [libc_cv_fpie=no])
 ])

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8a2d2459a35e00a5244d92a9b3cd9426674c10d2

commit 8a2d2459a35e00a5244d92a9b3cd9426674c10d2
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Jul 18 05:23:21 2017 -0700

    x86-64: Check PIC instead of SHARED in start.S
    
    PIC may be the default.

diff --git a/sysdeps/x86_64/start.S b/sysdeps/x86_64/start.S
index 62a00ea..9edd17b 100644
--- a/sysdeps/x86_64/start.S
+++ b/sysdeps/x86_64/start.S
@@ -96,7 +96,7 @@ ENTRY (_start)
 	   which grow downwards).  */
 	pushq %rsp
 
-#ifdef SHARED
+#ifdef PIC
 	/* Pass address of our own entry points to .fini and .init.  */
 	mov __libc_csu_fini@GOTPCREL(%rip), %R8_LP
 	mov __libc_csu_init@GOTPCREL(%rip), %RCX_LP

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=17d6b68a0a5b49281a4865c24e3f9f82b53fb96f

commit 17d6b68a0a5b49281a4865c24e3f9f82b53fb96f
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Jul 18 15:36:20 2017 -0700

    x86: Remove assembly versions of HAS_CPU_FEATURE/HAS_ARCH_FEATURE

diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h
index 3ed67f5..af52689 100644
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -127,63 +127,6 @@
 # define index_arch_Use_dl_runtime_resolve_slow FEATURE_INDEX_1*FEATURE_SIZE
 # define index_arch_Prefer_No_AVX512	FEATURE_INDEX_1*FEATURE_SIZE
 
-
-# if defined (_LIBC) && !IS_IN (nonlib)
-#  ifdef __x86_64__
-#   ifdef SHARED
-#    if IS_IN (rtld)
-#     define LOAD_RTLD_GLOBAL_RO_RDX
-#     define HAS_FEATURE(offset, field, name) \
-  testl $(bit_##field##_##name), \
-	_rtld_local_ro+offset+(index_##field##_##name)(%rip)
-#    else
-#      define LOAD_RTLD_GLOBAL_RO_RDX \
-  mov _rtld_global_ro@GOTPCREL(%rip), %RDX_LP
-#     define HAS_FEATURE(offset, field, name) \
-  testl $(bit_##field##_##name), \
-	RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+offset+(index_##field##_##name)(%rdx)
-#    endif
-#   else /* SHARED */
-#    define LOAD_RTLD_GLOBAL_RO_RDX
-#    define HAS_FEATURE(offset, field, name) \
-  testl $(bit_##field##_##name), \
-	_dl_x86_cpu_features+offset+(index_##field##_##name)(%rip)
-#   endif /* !SHARED */
-#  else  /* __x86_64__ */
-#   ifdef SHARED
-#    define LOAD_FUNC_GOT_EAX(func) \
-  leal func@GOTOFF(%edx), %eax
-#    if IS_IN (rtld)
-#    define LOAD_GOT_AND_RTLD_GLOBAL_RO \
-  LOAD_PIC_REG(dx)
-#     define HAS_FEATURE(offset, field, name) \
-  testl $(bit_##field##_##name), \
-	offset+(index_##field##_##name)+_rtld_local_ro@GOTOFF(%edx)
-#    else
-#     define LOAD_GOT_AND_RTLD_GLOBAL_RO \
-  LOAD_PIC_REG(dx); \
-  mov _rtld_global_ro@GOT(%edx), %ecx
-#     define HAS_FEATURE(offset, field, name) \
-  testl $(bit_##field##_##name), \
-	RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+offset+(index_##field##_##name)(%ecx)
-#    endif
-#   else  /* SHARED */
-#    define LOAD_FUNC_GOT_EAX(func) \
-  leal func, %eax
-#    define LOAD_GOT_AND_RTLD_GLOBAL_RO
-#    define HAS_FEATURE(offset, field, name) \
-  testl $(bit_##field##_##name), \
-	_dl_x86_cpu_features+offset+(index_##field##_##name)
-#   endif /* !SHARED */
-#  endif /* !__x86_64__ */
-# else /* _LIBC && !nonlib */
-#  error "Sorry, <cpu-features.h> is unimplemented for assembler"
-# endif /* !_LIBC || nonlib */
-
-/* HAS_* evaluates to true if we may use the feature at runtime.  */
-# define HAS_CPU_FEATURE(name)	HAS_FEATURE (CPUID_OFFSET, cpu, name)
-# define HAS_ARCH_FEATURE(name) HAS_FEATURE (FEATURE_OFFSET, arch, name)
-
 #else	/* __ASSEMBLER__ */
 
 enum

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=3a8af9336b0e5e73ed1c70e2edab8b6b9cd6f5ba

commit 3a8af9336b0e5e73ed1c70e2edab8b6b9cd6f5ba
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jul 19 06:54:03 2017 -0700

    i386: Convert IFUNC selectors to C

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 4a0c20c..bf75a99 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -24,7 +24,13 @@ sysdep_routines += bzero-sse2 memset-sse2 memcpy-ssse3 mempcpy-ssse3 \
 		   strcasecmp_l-sse4 strncase_l-sse4 \
 		   bcopy-sse2-unaligned memcpy-sse2-unaligned \
 		   mempcpy-sse2-unaligned memmove-sse2-unaligned \
-		   strcspn-c strpbrk-c strspn-c
+		   strcspn-c strpbrk-c strspn-c \
+		   bcopy-ia32 bzero-ia32 rawmemchr-ia32 \
+		   memchr-ia32 memcmp-ia32 memcpy-ia32 memmove-ia32 \
+		   mempcpy-ia32 memset-ia32 strcat-ia32 strchr-ia32 \
+		   strrchr-ia32 strcpy-ia32 strcmp-ia32 strcspn-ia32 \
+		   strpbrk-ia32 strspn-ia32 strlen-ia32 stpcpy-ia32 \
+		   stpncpy-ia32
 CFLAGS-varshift.c += -msse4
 CFLAGS-strcspn-c.c += -msse4
 CFLAGS-strpbrk-c.c += -msse4
@@ -42,3 +48,8 @@ libm-sysdep_routines += s_fma-fma s_fmaf-fma
 CFLAGS-s_fma-fma.c += -mavx -mfpmath=sse
 CFLAGS-s_fmaf-fma.c += -mavx -mfpmath=sse
 endif
+
+ifeq ($(subdir),debug)
+sysdep_routines += memcpy_chk-nonshared mempcpy_chk-nonshared \
+		   memmove_chk-nonshared memset_chk-nonshared
+endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/bcopy-ia32.S
similarity index 61%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/bcopy-ia32.S
index cf67333..606cd2e 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/bcopy-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcsrchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* bcopy optimized for i686.
+   Copyright (C) 2017 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
@@ -18,18 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
-#endif
+#define bcopy __bcopy_ia32
+#include <sysdeps/i386/i686/bcopy.S>
diff --git a/sysdeps/i386/i686/multiarch/bcopy.S b/sysdeps/i386/i686/multiarch/bcopy.S
deleted file mode 100644
index 877f82c..0000000
--- a/sysdeps/i386/i686/multiarch/bcopy.S
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Multiple versions of bcopy
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(bcopy)
-	.type	bcopy, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__bcopy_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__bcopy_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__bcopy_ssse3)
-	HAS_ARCH_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__bcopy_ssse3_rep)
-2:	ret
-END(bcopy)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __bcopy_ia32, @function; \
-	.p2align 4; \
-	.globl __bcopy_ia32; \
-	.hidden __bcopy_ia32; \
-	__bcopy_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __bcopy_ia32, .-__bcopy_ia32
-
-#endif
-
-#include "../bcopy.S"
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/bcopy.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/bcopy.c
index cf67333..70cd665 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/bcopy.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of bcopy.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define bcopy __redirect_bcopy
+# include <string.h>
+# undef bcopy
+
+# define SYMBOL_NAME bcopy
+# include "ifunc-memmove.h"
+
+libc_ifunc_redirected (__redirect_bcopy, bcopy, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i686/multiarch/bzero-ia32.S
similarity index 60%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i686/multiarch/bzero-ia32.S
index d241522..8df871f 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i686/multiarch/bzero-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* bzero optimized for i686.
+   Copyright (C) 2017 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
@@ -22,16 +20,19 @@
 #include <init-arch.h>
 
 #if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
+# define __bzero __bzero_ia32
+
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI___bzero; __GI___bzero = __bzero
+# endif
+
+# undef weak_alias
+# define weak_alias(original, alias)
+
+# include <sysdeps/i386/i686/bzero.S>
 #endif
diff --git a/sysdeps/i386/i686/multiarch/bzero.S b/sysdeps/i386/i686/multiarch/bzero.S
deleted file mode 100644
index 9dac490..0000000
--- a/sysdeps/i386/i686/multiarch/bzero.S
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Multiple versions of bzero
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(__bzero)
-	.type	__bzero, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__bzero_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX ( __bzero_sse2)
-	HAS_ARCH_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__bzero_sse2_rep)
-2:	ret
-END(__bzero)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __bzero_ia32, @function; \
-	.p2align 4; \
-	.globl __bzero_ia32; \
-	.hidden __bzero_ia32; \
-	__bzero_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __bzero_ia32, .-__bzero_ia32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI___bzero; __GI___bzero = __bzero_ia32
-# endif
-#endif
-
-#include "../bzero.S"
diff --git a/sysdeps/i386/i686/multiarch/wcschr.S b/sysdeps/i386/i686/multiarch/bzero.c
similarity index 66%
rename from sysdeps/i386/i686/multiarch/wcschr.S
rename to sysdeps/i386/i686/multiarch/bzero.c
index d3c65a6..0b029fd 100644
--- a/sysdeps/i386/i686/multiarch/wcschr.S
+++ b/sysdeps/i386/i686/multiarch/bzero.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcschr
+/* Multiple versions of bzero.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,19 +17,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(__wcschr)
-	.type	wcschr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcschr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcschr_sse2)
-2:	ret
-END(__wcschr)
-weak_alias (__wcschr, wcschr)
+# define bzero __redirect_bzero
+# include <string.h>
+# undef bzero
+
+# define SYMBOL_NAME bzero
+# include "ifunc-memset.h"
+
+libc_ifunc_redirected (__redirect_bzero, __bzero, IFUNC_SELECTOR ());
+
+weak_alias (__bzero, bzero)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/ifunc-memmove.h b/sysdeps/i386/i686/multiarch/ifunc-memmove.h
new file mode 100644
index 0000000..9c71414
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/ifunc-memmove.h
@@ -0,0 +1,45 @@
+/* Common definition for memmove/memmove_chk ifunc selections.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ia32) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2_unaligned)
+  attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ssse3) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ssse3_rep) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
+
+  if (CPU_FEATURES_ARCH_P (cpu_features, Fast_Unaligned_Load))
+    return OPTIMIZE (sse2_unaligned);
+
+  if (CPU_FEATURES_CPU_P (cpu_features, SSSE3))
+    {
+      if (CPU_FEATURES_ARCH_P (cpu_features, Fast_Rep_String))
+	return OPTIMIZE (ssse3_rep);
+
+      return OPTIMIZE (ssse3);
+    }
+
+  return OPTIMIZE (ia32);
+}
diff --git a/sysdeps/i386/i686/multiarch/memrchr.S b/sysdeps/i386/i686/multiarch/ifunc-memset.h
similarity index 56%
copy from sysdeps/i386/i686/multiarch/memrchr.S
copy to sysdeps/i386/i686/multiarch/ifunc-memset.h
index d4253a5..77933fd 100644
--- a/sysdeps/i386/i686/multiarch/memrchr.S
+++ b/sysdeps/i386/i686/multiarch/ifunc-memset.h
@@ -1,7 +1,6 @@
-/* Multiple versions of memrchr
+/* Common definition for memset/memset_chk ifunc selections.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,28 +17,24 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
 #include <init-arch.h>
 
-#if IS_IN (libc)
-	.text
-ENTRY(__memrchr)
-	.type	__memrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	3f
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ia32) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2_rep) attribute_hidden;
 
-	LOAD_FUNC_GOT_EAX (__memrchr_sse2)
-	ret
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
 
-2:	LOAD_FUNC_GOT_EAX (__memrchr_ia32)
-	ret
+  if (CPU_FEATURES_CPU_P (cpu_features, SSE2))
+    {
+      if (CPU_FEATURES_ARCH_P (cpu_features, Fast_Rep_String))
+	return OPTIMIZE (sse2_rep);
 
-3:	LOAD_FUNC_GOT_EAX (__memrchr_sse2_bsf)
-	ret
-END(__memrchr)
+      return OPTIMIZE (sse2);
+    }
 
-weak_alias(__memrchr, memrchr)
-#endif
+  return OPTIMIZE (ia32);
+}
diff --git a/sysdeps/i386/i686/multiarch/memrchr.S b/sysdeps/i386/i686/multiarch/ifunc-sse2-bsf.h
similarity index 55%
copy from sysdeps/i386/i686/multiarch/memrchr.S
copy to sysdeps/i386/i686/multiarch/ifunc-sse2-bsf.h
index d4253a5..0b9b99d 100644
--- a/sysdeps/i386/i686/multiarch/memrchr.S
+++ b/sysdeps/i386/i686/multiarch/ifunc-sse2-bsf.h
@@ -1,7 +1,6 @@
-/* Multiple versions of memrchr
+/* Common definition for ifunc selections optimized with SSE2 and BSF.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,28 +17,24 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
 #include <init-arch.h>
 
-#if IS_IN (libc)
-	.text
-ENTRY(__memrchr)
-	.type	__memrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	3f
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ia32) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2_bsf) attribute_hidden;
 
-	LOAD_FUNC_GOT_EAX (__memrchr_sse2)
-	ret
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
 
-2:	LOAD_FUNC_GOT_EAX (__memrchr_ia32)
-	ret
+  if (CPU_FEATURES_CPU_P (cpu_features, SSE2))
+    {
+      if (CPU_FEATURES_ARCH_P (cpu_features, Slow_BSF))
+	return OPTIMIZE (sse2);
 
-3:	LOAD_FUNC_GOT_EAX (__memrchr_sse2_bsf)
-	ret
-END(__memrchr)
+      return OPTIMIZE (sse2_bsf);
+    }
 
-weak_alias(__memrchr, memrchr)
-#endif
+  return OPTIMIZE (ia32);
+}
diff --git a/sysdeps/i386/i686/multiarch/memrchr.S b/sysdeps/i386/i686/multiarch/ifunc-sse2-ssse3.h
similarity index 54%
copy from sysdeps/i386/i686/multiarch/memrchr.S
copy to sysdeps/i386/i686/multiarch/ifunc-sse2-ssse3.h
index d4253a5..a4c3645 100644
--- a/sysdeps/i386/i686/multiarch/memrchr.S
+++ b/sysdeps/i386/i686/multiarch/ifunc-sse2-ssse3.h
@@ -1,7 +1,7 @@
-/* Multiple versions of memrchr
+/* Common definition for ifunc selections optimized with SSE2 and
+   SSSE3.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,28 +18,23 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
 #include <init-arch.h>
 
-#if IS_IN (libc)
-	.text
-ENTRY(__memrchr)
-	.type	__memrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	3f
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ia32) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ssse3) attribute_hidden;
 
-	LOAD_FUNC_GOT_EAX (__memrchr_sse2)
-	ret
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
 
-2:	LOAD_FUNC_GOT_EAX (__memrchr_ia32)
-	ret
+  if (CPU_FEATURES_CPU_P (cpu_features, SSE2)
+      && CPU_FEATURES_ARCH_P (cpu_features, Fast_Rep_String))
+    return OPTIMIZE (sse2);
 
-3:	LOAD_FUNC_GOT_EAX (__memrchr_sse2_bsf)
-	ret
-END(__memrchr)
+  if (CPU_FEATURES_CPU_P (cpu_features, SSSE3))
+    return OPTIMIZE (ssse3);
 
-weak_alias(__memrchr, memrchr)
-#endif
+  return OPTIMIZE (ia32);
+}
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i686/multiarch/ifunc-sse2.h
similarity index 63%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i686/multiarch/ifunc-sse2.h
index d241522..f4868aa 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i686/multiarch/ifunc-sse2.h
@@ -1,7 +1,6 @@
-/* Multiple versions of strnlen
+/* Common definition for ifunc selections optimized with SSE2.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,18 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
 #include <init-arch.h>
 
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
-#endif
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ia32) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
+
+  if (CPU_FEATURES_CPU_P (cpu_features, SSE2))
+    return OPTIMIZE (sse2);
+
+  return OPTIMIZE (ia32);
+}
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i686/multiarch/ifunc-sse4_2.h
similarity index 63%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i686/multiarch/ifunc-sse4_2.h
index d241522..d4f883a 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i686/multiarch/ifunc-sse4_2.h
@@ -1,7 +1,6 @@
-/* Multiple versions of strnlen
+/* Common definition for ifunc selections optimized with SSE4_2.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,18 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
 #include <init-arch.h>
 
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
-#endif
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ia32) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
+
+  if (CPU_FEATURES_CPU_P (cpu_features, SSE4_2))
+    return OPTIMIZE (sse42);
+
+  return OPTIMIZE (ia32);
+}
diff --git a/sysdeps/i386/i686/multiarch/memrchr.S b/sysdeps/i386/i686/multiarch/ifunc-ssse3-sse4_2.h
similarity index 56%
copy from sysdeps/i386/i686/multiarch/memrchr.S
copy to sysdeps/i386/i686/multiarch/ifunc-ssse3-sse4_2.h
index d4253a5..e19d413 100644
--- a/sysdeps/i386/i686/multiarch/memrchr.S
+++ b/sysdeps/i386/i686/multiarch/ifunc-ssse3-sse4_2.h
@@ -1,7 +1,7 @@
-/* Multiple versions of memrchr
+/* Common definition for ifunc selections optimized with SSSE3 and
+   SSE4_2.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,28 +18,22 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
 #include <init-arch.h>
 
-#if IS_IN (libc)
-	.text
-ENTRY(__memrchr)
-	.type	__memrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	3f
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ia32) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ssse3) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse4_2) attribute_hidden;
 
-	LOAD_FUNC_GOT_EAX (__memrchr_sse2)
-	ret
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
 
-2:	LOAD_FUNC_GOT_EAX (__memrchr_ia32)
-	ret
+  if (CPU_FEATURES_CPU_P (cpu_features, SSE4_2))
+    return OPTIMIZE (sse4_2);
 
-3:	LOAD_FUNC_GOT_EAX (__memrchr_sse2_bsf)
-	ret
-END(__memrchr)
+  if (CPU_FEATURES_CPU_P (cpu_features, SSSE3))
+    return OPTIMIZE (ssse3);
 
-weak_alias(__memrchr, memrchr)
-#endif
+  return OPTIMIZE (ia32);
+}
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/memchr-ia32.S
similarity index 59%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/memchr-ia32.S
index 6ef9b6e..2663821 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/memchr-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcslen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* memchr optimized for i686.
+   Copyright (C) 2017 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
@@ -18,20 +16,20 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define __memchr __memchr_ia32
+
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_memchr; __GI_memchr = __memchr
+# endif
 
-weak_alias(__wcslen, wcslen)
+# undef weak_alias
+# define weak_alias(original, alias)
 #endif
+
+#include <sysdeps/i386/memchr.S>
diff --git a/sysdeps/i386/i686/multiarch/memchr.S b/sysdeps/i386/i686/multiarch/memchr.S
deleted file mode 100644
index bd0dace..0000000
--- a/sysdeps/i386/i686/multiarch/memchr.S
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Multiple versions of memchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__memchr)
-	.type	__memchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	3f
-
-	LOAD_FUNC_GOT_EAX ( __memchr_sse2)
-	ret
-
-2:	LOAD_FUNC_GOT_EAX (__memchr_ia32)
-	ret
-
-3:	LOAD_FUNC_GOT_EAX (__memchr_sse2_bsf)
-	ret
-END(__memchr)
-
-weak_alias(__memchr, memchr)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __memchr_ia32, @function; \
-	.globl __memchr_ia32; \
-	.p2align 4; \
-	__memchr_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __memchr_ia32, .-__memchr_ia32
-
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_memchr; __GI_memchr = __memchr_ia32
-
-#endif
-#include "../../memchr.S"
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/memchr.c
similarity index 66%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/memchr.c
index 6ef9b6e..f7cbb14 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/memchr.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcslen
+/* Multiple versions of memchr.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define memchr __redirect_memchr
+# include <string.h>
+# undef memchr
+
+# define SYMBOL_NAME memchr
+# include "ifunc-sse2-bsf.h"
+
+libc_ifunc_redirected (__redirect_memchr, __memchr, IFUNC_SELECTOR ());
 
-weak_alias(__wcslen, wcslen)
+weak_alias (__memchr, memchr)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/memcmp-ia32.S
similarity index 59%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/memcmp-ia32.S
index 6ef9b6e..737a914 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/memcmp-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcslen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* memcmp optimized for i686.
+   Copyright (C) 2017 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
@@ -18,20 +16,20 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define memcmp __memcmp_ia32
+
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_memcmp; __GI_memcmp = memcmp
+# endif
 
-weak_alias(__wcslen, wcslen)
+# undef weak_alias
+# define weak_alias(original, alias)
 #endif
+
+#include <sysdeps/i386/i686/memcmp.S>
diff --git a/sysdeps/i386/i686/multiarch/memcmp.S b/sysdeps/i386/i686/multiarch/memcmp.S
deleted file mode 100644
index 1fc5994..0000000
--- a/sysdeps/i386/i686/multiarch/memcmp.S
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Multiple versions of memcmp
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc. */
-#if IS_IN (libc)
-	.text
-ENTRY(memcmp)
-	.type	memcmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memcmp_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcmp_ssse3)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcmp_sse4_2)
-2:	ret
-END(memcmp)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __memcmp_ia32, @function; \
-	.p2align 4; \
-	.globl __memcmp_ia32; \
-	.hidden __memcmp_ia32; \
-	__memcmp_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __memcmp_ia32, .-__memcmp_ia32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_memcmp; __GI_memcmp = __memcmp_ia32
-# endif
-#endif
-
-#include "../memcmp.S"
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i686/multiarch/memcmp.c
similarity index 65%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i686/multiarch/memcmp.c
index d241522..5763c94 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i686/multiarch/memcmp.c
@@ -1,7 +1,6 @@
-/* Multiple versions of strnlen
+/* Multiple versions of memcmp.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
+# define memcmp __redirect_memcmp
+# include <string.h>
+# undef memcmp
+
+# define SYMBOL_NAME memcmp
+# include "ifunc-ssse3-sse4_2.h"
+
+libc_ifunc_redirected (__redirect_memcmp, memcmp, IFUNC_SELECTOR ());
 
-weak_alias(__strnlen, strnlen)
+weak_alias (memcmp, bcmp)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/memcpy-ia32.S
similarity index 59%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/memcpy-ia32.S
index 6ef9b6e..51ec4d4 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/memcpy-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcslen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* memcpy optimized for i686.
+   Copyright (C) 2017 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
@@ -18,20 +16,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#if defined SHARED && IS_IN (libc)
+# define memcpy __memcpy_ia32
+# define __memcpy_chk __memcpy_chk_ia32
 
-#if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
-
-weak_alias(__wcslen, wcslen)
+# undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+# define libc_hidden_builtin_def(name) \
+	.globl __GI_memcpy; __GI_memcpy = memcpy
 #endif
+
+#include <sysdeps/i386/i686/memcpy.S>
diff --git a/sysdeps/i386/i686/multiarch/memcpy.S b/sysdeps/i386/i686/multiarch/memcpy.S
deleted file mode 100644
index f725944..0000000
--- a/sysdeps/i386/i686/multiarch/memcpy.S
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Multiple versions of memcpy
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib and for
-   DSO.  In static binaries we need memcpy before the initialization
-   happened.  */
-#if defined SHARED && IS_IN (libc)
-	.text
-ENTRY(memcpy)
-	.type	memcpy, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memcpy_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_ssse3)
-	HAS_ARCH_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_ssse3_rep)
-2:	ret
-END(memcpy)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __memcpy_ia32, @function; \
-	.p2align 4; \
-	.globl __memcpy_ia32; \
-	.hidden __memcpy_ia32; \
-	__memcpy_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __memcpy_ia32, .-__memcpy_ia32
-
-# undef ENTRY_CHK
-# define ENTRY_CHK(name) \
-	.type __memcpy_chk_ia32, @function; \
-	.globl __memcpy_chk_ia32; \
-	.p2align 4; \
-	__memcpy_chk_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END_CHK
-# define END_CHK(name) \
-	cfi_endproc; .size __memcpy_chk_ia32, .-__memcpy_chk_ia32
-
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_memcpy; __GI_memcpy = __memcpy_ia32
-#endif
-
-#include "../memcpy.S"
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i686/multiarch/memcpy.c
similarity index 62%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i686/multiarch/memcpy.c
index d241522..3379122 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i686/multiarch/memcpy.c
@@ -1,7 +1,6 @@
-/* Multiple versions of strnlen
+/* Multiple versions of memcpy.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+/* Define multiple versions only for the definition in lib and for
+   DSO.  In static binaries we need memcpy before the initialization
+   happened.  */
+#if defined SHARED && IS_IN (libc)
+# define memcpy __redirect_memcpy
+# include <string.h>
+# undef memcpy
 
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
+# define SYMBOL_NAME memcpy
+# include "ifunc-memmove.h"
 
-weak_alias(__strnlen, strnlen)
+libc_ifunc_redirected (__redirect_memcpy, memcpy, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/memcpy_chk-nonshared.S
similarity index 61%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/memcpy_chk-nonshared.S
index cf67333..91c01f7 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/memcpy_chk-nonshared.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcsrchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* Non-shared version of memcpy_chk for i686.
+   Copyright (C) 2017 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
@@ -18,18 +16,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+#if IS_IN (libc) && !defined SHARED
+# include <sysdeps/i386/memcpy_chk.S>
 #endif
diff --git a/sysdeps/i386/i686/multiarch/memcpy_chk.S b/sysdeps/i386/i686/multiarch/memcpy_chk.S
deleted file mode 100644
index 1b4fbe2..0000000
--- a/sysdeps/i386/i686/multiarch/memcpy_chk.S
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Multiple versions of __memcpy_chk
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib and for
-   DSO.  There are no multiarch memcpy functions for static binaries.
- */
-#if IS_IN (libc)
-# ifdef SHARED
-	.text
-ENTRY(__memcpy_chk)
-	.type	__memcpy_chk, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memcpy_chk_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_chk_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_chk_ssse3)
-	HAS_ARCH_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_chk_ssse3_rep)
-2:	ret
-END(__memcpy_chk)
-# else
-#  include "../memcpy_chk.S"
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/memcpy_chk.c
similarity index 64%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/memcpy_chk.c
index cf67333..6347c21 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/memcpy_chk.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of __memcpy_chk
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,15 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+/* Define multiple versions only for the definition in libc.so. */
+#if IS_IN (libc) && defined SHARED
+# define __memcpy_chk __redirect_memcpy_chk
+# include <string.h>
+# undef __memcpy_chk
 
-#if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define SYMBOL_NAME memcpy_chk
+# include "ifunc-memmove.h"
+
+libc_ifunc_redirected (__redirect_memcpy_chk, __memcpy_chk,
+		       IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i686/multiarch/memmove-ia32.S
similarity index 59%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i686/multiarch/memmove-ia32.S
index d241522..7f212dc 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i686/multiarch/memmove-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* memmove optimized for i686.
+   Copyright (C) 2017 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
@@ -18,20 +16,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#if defined SHARED && IS_IN (libc)
+# define memmove __memmove_ia32
+# define __memmove_chk __memmove_chk_ia32
 
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
+# undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+# define libc_hidden_builtin_def(name) \
+	.globl __GI_memmove; __GI_memmove = memmove
 #endif
+
+#include <sysdeps/i386/i686/memmove.S>
diff --git a/sysdeps/i386/i686/multiarch/memmove.S b/sysdeps/i386/i686/multiarch/memmove.S
deleted file mode 100644
index 6eb418c..0000000
--- a/sysdeps/i386/i686/multiarch/memmove.S
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Multiple versions of memmove
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(memmove)
-	.type	memmove, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memmove_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_ssse3)
-	HAS_ARCH_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_ssse3_rep)
-2:	ret
-END(memmove)
-
-# ifdef SHARED
-#  undef ENTRY
-#  define ENTRY(name) \
-	.type __memmove_ia32, @function; \
-	.p2align 4; \
-	.globl __memmove_ia32; \
-	.hidden __memmove_ia32; \
-	__memmove_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# else
-#  undef ENTRY
-#  define ENTRY(name) \
-	.type __memmove_ia32, @function; \
-	.globl __memmove_ia32; \
-	.p2align 4; \
-	__memmove_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# endif
-
-# undef END
-# define END(name) \
-	cfi_endproc; .size __memmove_ia32, .-__memmove_ia32
-
-# undef ENTRY_CHK
-# define ENTRY_CHK(name) \
-	.type __memmove_chk_ia32, @function; \
-	.globl __memmove_chk_ia32; \
-	.p2align 4; \
-	__memmove_chk_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END_CHK
-# define END_CHK(name) \
-	cfi_endproc; .size __memmove_chk_ia32, .-__memmove_chk_ia32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_memmove; __GI_memmove = __memmove_ia32
-# endif
-#endif
-
-#include "../memmove.S"
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i686/multiarch/memmove.c
similarity index 62%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i686/multiarch/memmove.c
index d241522..1cbd87f 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i686/multiarch/memmove.c
@@ -1,7 +1,6 @@
-/* Multiple versions of strnlen
+/* Multiple versions of memmove.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+/* Define multiple versions only for the definition in lib and for
+   DSO.  In static binaries we need memmove before the initialization
+   happened.  */
+#if defined SHARED && IS_IN (libc)
+# define memmove __redirect_memmove
+# include <string.h>
+# undef memmove
 
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
+# define SYMBOL_NAME memmove
+# include "ifunc-memmove.h"
 
-weak_alias(__strnlen, strnlen)
+libc_ifunc_redirected (__redirect_memmove, memmove, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/memmove_chk-nonshared.S
similarity index 61%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/memmove_chk-nonshared.S
index cf67333..514393d 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/memmove_chk-nonshared.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcsrchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* Non-shared version of memmmove_chk for i686.
+   Copyright (C) 2017 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
@@ -18,18 +16,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+#if IS_IN (libc) && !defined SHARED
+# include <sysdeps/i386/memmove_chk.S>
 #endif
diff --git a/sysdeps/i386/i686/multiarch/memmove_chk.S b/sysdeps/i386/i686/multiarch/memmove_chk.S
deleted file mode 100644
index 314834c..0000000
--- a/sysdeps/i386/i686/multiarch/memmove_chk.S
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Multiple versions of __memmove_chk
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(__memmove_chk)
-	.type	__memmove_chk, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memmove_chk_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_chk_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_chk_ssse3)
-	HAS_ARCH_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_chk_ssse3_rep)
-2:	ret
-END(__memmove_chk)
-
-# ifndef SHARED
-	.type __memmove_chk_sse2_unaligned, @function
-	.p2align 4;
-__memmove_chk_sse2_unaligned:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memmove_sse2_unaligned
-	cfi_endproc
-	.size __memmove_chk_sse2_unaligned, .-__memmove_chk_sse2_unaligned
-
-	.type __memmove_chk_ssse3, @function
-	.p2align 4;
-__memmove_chk_ssse3:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memmove_ssse3
-	cfi_endproc
-	.size __memmove_chk_ssse3, .-__memmove_chk_ssse3
-
-	.type __memmove_chk_ssse3_rep, @function
-	.p2align 4;
-__memmove_chk_ssse3_rep:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memmove_ssse3_rep
-	cfi_endproc
-	.size __memmove_chk_ssse3_rep, .-__memmove_chk_ssse3_rep
-
-	.type __memmove_chk_ia32, @function
-	.p2align 4;
-__memmove_chk_ia32:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memmove_ia32
-	cfi_endproc
-	.size __memmove_chk_ia32, .-__memmove_chk_ia32
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/memmove_chk.c
similarity index 64%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/memmove_chk.c
index 6ef9b6e..44339d6 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/memmove_chk.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcslen
+/* Multiple versions of __memmove_chk
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,15 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+/* Define multiple versions only for the definition in libc.so. */
+#if IS_IN (libc) && defined SHARED
+# define __memmove_chk __redirect_memmove_chk
+# include <string.h>
+# undef __memmove_chk
 
-#if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define SYMBOL_NAME memmove_chk
+# include "ifunc-memmove.h"
 
-weak_alias(__wcslen, wcslen)
+libc_ifunc_redirected (__redirect_memmove_chk, __memmove_chk,
+		       IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/strchr.S b/sysdeps/i386/i686/multiarch/mempcpy-ia32.S
similarity index 53%
rename from sysdeps/i386/i686/multiarch/strchr.S
rename to sysdeps/i386/i686/multiarch/mempcpy-ia32.S
index 5b97b1c..b6d5721 100644
--- a/sysdeps/i386/i686/multiarch/strchr.S
+++ b/sysdeps/i386/i686/multiarch/mempcpy-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* mempcpy optimized for i686.
+   Copyright (C) 2017 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
@@ -18,40 +16,22 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#if defined SHARED && IS_IN (libc)
+# define __mempcpy __mempcpy_ia32
+# define __mempcpy_chk __mempcpy_chk_ia32
 
-#if IS_IN (libc)
-	.text
-ENTRY(strchr)
-	.type	strchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strchr_sse2_bsf)
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strchr_sse2)
-2:	ret
-END(strchr)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strchr_ia32, @function; \
-	.globl __strchr_ia32; \
-	.p2align 4; \
-	__strchr_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strchr_ia32, .-__strchr_ia32
+# undef libc_hidden_def
 # undef libc_hidden_builtin_def
 /* IFUNC doesn't work with the hidden functions in shared library since
    they will be called without setting up EBX needed for PLT which is
    used by IFUNC.  */
+# define libc_hidden_def(name) \
+	.globl __GI___mempcpy; __GI___mempcpy = __mempcpy
 # define libc_hidden_builtin_def(name) \
-	.globl __GI_strchr; __GI_strchr = __strchr_ia32
+	.globl __GI_mempcpy; __GI_mempcpy = __mempcpy
+
+# undef weak_alias
+# define weak_alias(original, alias)
 #endif
 
-#include "../../i586/strchr.S"
+#include <sysdeps/i386/i686/mempcpy.S>
diff --git a/sysdeps/i386/i686/multiarch/mempcpy.S b/sysdeps/i386/i686/multiarch/mempcpy.S
deleted file mode 100644
index 06e377f..0000000
--- a/sysdeps/i386/i686/multiarch/mempcpy.S
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Multiple versions of mempcpy
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib and for
-   DSO.  In static binaries we need mempcpy before the initialization
-   happened.  */
-#if defined SHARED && IS_IN (libc)
-	.text
-ENTRY(__mempcpy)
-	.type	__mempcpy, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__mempcpy_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_ssse3)
-	HAS_ARCH_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_ssse3_rep)
-2:	ret
-END(__mempcpy)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __mempcpy_ia32, @function; \
-	.p2align 4; \
-	.globl __mempcpy_ia32; \
-	.hidden __mempcpy_ia32; \
-	__mempcpy_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __mempcpy_ia32, .-__mempcpy_ia32
-
-# undef ENTRY_CHK
-# define ENTRY_CHK(name) \
-	.type __mempcpy_chk_ia32, @function; \
-	.globl __mempcpy_chk_ia32; \
-	.p2align 4; \
-	__mempcpy_chk_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END_CHK
-# define END_CHK(name) \
-	cfi_endproc; .size __mempcpy_chk_ia32, .-__mempcpy_chk_ia32
-
-# undef libc_hidden_def
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_def(name) \
-	.globl __GI_mempcpy; __GI_mempcpy = __mempcpy_ia32
-# define libc_hidden_builtin_def(name) \
-	.globl __GI___mempcpy; __GI___mempcpy = __mempcpy_ia32
-#endif
-
-#include "../mempcpy.S"
diff --git a/sysdeps/i386/i686/multiarch/wcscmp.S b/sysdeps/i386/i686/multiarch/mempcpy.c
similarity index 56%
rename from sysdeps/i386/i686/multiarch/wcscmp.S
rename to sysdeps/i386/i686/multiarch/mempcpy.c
index 7118bdd..46d7f13 100644
--- a/sysdeps/i386/i686/multiarch/wcscmp.S
+++ b/sysdeps/i386/i686/multiarch/mempcpy.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcscmp
+/* Multiple versions of mempcpy.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,22 +17,22 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc and for the
-   DSO.  In static binaries, we need wcscmp before the initialization
+/* Define multiple versions only for the definition in lib and for
+   DSO.  In static binaries we need memcpy before the initialization
    happened.  */
-#if IS_IN (libc)
-	.text
-ENTRY(__wcscmp)
-	.type	__wcscmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcscmp_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcscmp_sse2)
-2:	ret
-END(__wcscmp)
-weak_alias (__wcscmp, wcscmp)
+#if defined SHARED && IS_IN (libc)
+# define mempcpy __redirect_mempcpy
+# define __mempcpy __redirect___mempcpy
+# define NO_MEMPCPY_STPCPY_REDIRECT
+# define __NO_STRING_INLINES
+# include <string.h>
+# undef mempcpy
+# undef __mempcpy
+
+# define SYMBOL_NAME mempcpy
+# include "ifunc-memmove.h"
+
+libc_ifunc_redirected (__redirect_mempcpy, __mempcpy, IFUNC_SELECTOR ());
+
+weak_alias (__mempcpy, mempcpy)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/mempcpy_chk-nonshared.S
similarity index 61%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/mempcpy_chk-nonshared.S
index cf67333..6e31a5d 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/mempcpy_chk-nonshared.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcsrchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* Non-shared version of mempcpy_chk for i686.
+   Copyright (C) 2017 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
@@ -18,18 +16,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+#if IS_IN (libc) && !defined SHARED
+# include <sysdeps/i386/mempcpy_chk.S>
 #endif
diff --git a/sysdeps/i386/i686/multiarch/mempcpy_chk.S b/sysdeps/i386/i686/multiarch/mempcpy_chk.S
deleted file mode 100644
index e13e524..0000000
--- a/sysdeps/i386/i686/multiarch/mempcpy_chk.S
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Multiple versions of __mempcpy_chk
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib and for
-   DSO.  There are no multiarch mempcpy functions for static binaries.
- */
-#if IS_IN (libc)
-# ifdef SHARED
-	.text
-ENTRY(__mempcpy_chk)
-	.type	__mempcpy_chk, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__mempcpy_chk_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_chk_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_chk_ssse3)
-	HAS_ARCH_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_chk_ssse3_rep)
-2:	ret
-END(__mempcpy_chk)
-# else
-#  include "../mempcpy_chk.S"
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/mempcpy_chk.c
similarity index 64%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/mempcpy_chk.c
index 6ef9b6e..c73273e 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/mempcpy_chk.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcslen
+/* Multiple versions of __mempcpy_chk
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,15 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+/* Define multiple versions only for the definition in libc.so. */
+#if IS_IN (libc) && defined SHARED
+# define __mempcpy_chk __redirect_mempcpy_chk
+# include <string.h>
+# undef __mempcpy_chk
 
-#if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define SYMBOL_NAME mempcpy_chk
+# include "ifunc-memmove.h"
 
-weak_alias(__wcslen, wcslen)
+libc_ifunc_redirected (__redirect_mempcpy_chk, __mempcpy_chk,
+		       IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/memrchr.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/memrchr.c
index cf67333..e8edba0 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/memrchr.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of memrchr.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define memrchr __redirect_memrchr
+# include <string.h>
+# undef memrchr
+
+# define SYMBOL_NAME memrchr
+# include "ifunc-sse2-bsf.h"
+
+libc_ifunc_redirected (__redirect_memrchr, __memrchr, IFUNC_SELECTOR ());
+
+weak_alias (__memrchr, memrchr)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/memset-ia32.S
similarity index 60%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/memset-ia32.S
index 6ef9b6e..a91f1b8 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/memset-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcslen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* memset optimized for i686.
+   Copyright (C) 2017 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
@@ -18,20 +16,18 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define memset __memset_ia32
+# define __memset_chk __memset_chk_ia32
 
-weak_alias(__wcslen, wcslen)
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_memset; __GI_memset = memset
+# endif
 #endif
+
+#include <sysdeps/i386/i686/memset.S>
diff --git a/sysdeps/i386/i686/multiarch/memset.S b/sysdeps/i386/i686/multiarch/memset.S
deleted file mode 100644
index f601663..0000000
--- a/sysdeps/i386/i686/multiarch/memset.S
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Multiple versions of memset
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(memset)
-	.type	memset, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memset_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_sse2)
-	HAS_ARCH_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_sse2_rep)
-2:	ret
-END(memset)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __memset_ia32, @function; \
-	.globl __memset_ia32; \
-	.p2align 4; \
-	__memset_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __memset_ia32, .-__memset_ia32
-
-# undef ENTRY_CHK
-# define ENTRY_CHK(name) \
-	.type __memset_chk_ia32, @function; \
-	.globl __memset_chk_ia32; \
-	.p2align 4; \
-	__memset_chk_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END_CHK
-# define END_CHK(name) \
-	cfi_endproc; .size __memset_chk_ia32, .-__memset_chk_ia32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_memset; __GI_memset = __memset_ia32
-# endif
-
-# undef strong_alias
-# define strong_alias(original, alias)
-#endif
-
-#include "../memset.S"
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/memset.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/memset.c
index cf67333..0bc0418 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/memset.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of memset.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define memset __redirect_memset
+# include <string.h>
+# undef memset
+
+# define SYMBOL_NAME memset
+# include "ifunc-memset.h"
+
+libc_ifunc_redirected (__redirect_memset, memset, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/memset_chk-nonshared.S
similarity index 61%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/memset_chk-nonshared.S
index cf67333..038cff6 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/memset_chk-nonshared.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcsrchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* Non-shared version of memset_chk for i686.
+   Copyright (C) 2017 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
@@ -18,18 +16,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+#if IS_IN (libc) && !defined SHARED
+# include <sysdeps/i386/memset_chk.S>
 #endif
diff --git a/sysdeps/i386/i686/multiarch/memset_chk.S b/sysdeps/i386/i686/multiarch/memset_chk.S
deleted file mode 100644
index 573cf42..0000000
--- a/sysdeps/i386/i686/multiarch/memset_chk.S
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Multiple versions of __memset_chk
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(__memset_chk)
-	.type	__memset_chk, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memset_chk_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_chk_sse2)
-	HAS_ARCH_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_chk_sse2_rep)
-2:	ret
-END(__memset_chk)
-
-# ifdef SHARED
-strong_alias (__memset_chk, __memset_zero_constant_len_parameter)
-	.section .gnu.warning.__memset_zero_constant_len_parameter
-	.string "memset used with constant zero length parameter; this could be due to transposed parameters"
-# else
-	.text
-	.type __memset_chk_sse2, @function
-	.p2align 4;
-__memset_chk_sse2:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memset_sse2
-	cfi_endproc
-	.size __memset_chk_sse2, .-__memset_chk_sse2
-
-	.type __memset_chk_sse2_rep, @function
-	.p2align 4;
-__memset_chk_sse2_rep:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memset_sse2_rep
-	cfi_endproc
-	.size __memset_chk_sse2_rep, .-__memset_chk_sse2_rep
-
-	.type __memset_chk_ia32, @function
-	.p2align 4;
-__memset_chk_ia32:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memset_ia32
-	cfi_endproc
-	.size __memset_chk_ia32, .-__memset_chk_ia32
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/memset_chk.c
similarity index 64%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/memset_chk.c
index cf67333..6996334 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/memset_chk.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of __memset_chk
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+/* Define multiple versions only for the definition in libc.so. */
+#if IS_IN (libc) && defined SHARED
+# define __memset_chk __redirect_memset_chk
+# include <string.h>
+# undef __memset_chk
+
+# define SYMBOL_NAME memset_chk
+# include "ifunc-memset.h"
+
+libc_ifunc_redirected (__redirect_memset_chk, __memset_chk,
+		       IFUNC_SELECTOR ());
 
-#if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i686/multiarch/rawmemchr-ia32.S
similarity index 59%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i686/multiarch/rawmemchr-ia32.S
index d241522..c182450 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i686/multiarch/rawmemchr-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* rawmemchr optimized for i686.
+   Copyright (C) 2017 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
@@ -18,20 +16,20 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
+# define __rawmemchr __rawmemchr_ia32
+
+# ifdef SHARED
+#  undef libc_hidden_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_def(name) \
+	.globl __GI___rawmemchr; __GI___rawmemchr = __rawmemchr
+# endif
 
-weak_alias(__strnlen, strnlen)
+# undef weak_alias
+# define weak_alias(original, alias)
 #endif
+
+#include <sysdeps/i386/rawmemchr.S>
diff --git a/sysdeps/i386/i686/multiarch/rawmemchr.S b/sysdeps/i386/i686/multiarch/rawmemchr.S
deleted file mode 100644
index 0a41d63..0000000
--- a/sysdeps/i386/i686/multiarch/rawmemchr.S
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Multiple versions of rawmemchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__rawmemchr)
-	.type	__rawmemchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	3f
-
-	LOAD_FUNC_GOT_EAX (__rawmemchr_sse2)
-	ret
-
-2:	LOAD_FUNC_GOT_EAX (__rawmemchr_ia32)
-	ret
-
-3:	LOAD_FUNC_GOT_EAX (__rawmemchr_sse2_bsf)
-	ret
-END(__rawmemchr)
-
-weak_alias(__rawmemchr, rawmemchr)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __rawmemchr_ia32, @function; \
-	.globl __rawmemchr_ia32; \
-	.p2align 4; \
-	__rawmemchr_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __rawmemchr_ia32, .-__rawmemchr_ia32
-
-# undef libc_hidden_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_def(name) \
-	.globl __GI___rawmemchr; __GI___rawmemchr = __rawmemchr_ia32
-
-#endif
-#include "../../rawmemchr.S"
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i686/multiarch/rawmemchr.c
similarity index 62%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i686/multiarch/rawmemchr.c
index d241522..1cbc453 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i686/multiarch/rawmemchr.c
@@ -1,7 +1,6 @@
-/* Multiple versions of strnlen
+/* Multiple versions of rawmemchr.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,19 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
+# define rawmemchr __redirect_rawmemchr
+# define __rawmemchr __redirect___rawmemchr
+# include <string.h>
+# undef rawmemchr
+# undef __rawmemchr
+
+# define SYMBOL_NAME rawmemchr
+# include "ifunc-sse2-bsf.h"
+
+libc_ifunc_redirected (__redirect_rawmemchr, __rawmemchr,
+		       IFUNC_SELECTOR ());
 
-weak_alias(__strnlen, strnlen)
+weak_alias (__rawmemchr, rawmemchr)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/memrchr.S b/sysdeps/i386/i686/multiarch/stpcpy-ia32.S
similarity index 56%
copy from sysdeps/i386/i686/multiarch/memrchr.S
copy to sysdeps/i386/i686/multiarch/stpcpy-ia32.S
index d4253a5..679d530 100644
--- a/sysdeps/i386/i686/multiarch/memrchr.S
+++ b/sysdeps/i386/i686/multiarch/stpcpy-ia32.S
@@ -1,7 +1,6 @@
-/* Multiple versions of memrchr
+/* stpcpy optimized for i686.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,28 +17,23 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__memrchr)
-	.type	__memrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	3f
-
-	LOAD_FUNC_GOT_EAX (__memrchr_sse2)
-	ret
-
-2:	LOAD_FUNC_GOT_EAX (__memrchr_ia32)
-	ret
-
-3:	LOAD_FUNC_GOT_EAX (__memrchr_sse2_bsf)
-	ret
-END(__memrchr)
-
-weak_alias(__memrchr, memrchr)
+# define __stpcpy __stpcpy_ia32
+
+# ifdef SHARED
+#  undef libc_hidden_def
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_def(name) \
+	.globl __GI___stpcpy; __GI___stpcpy = __stpcpy
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_stpcpy; __GI_stpcpy = __stpcpy
+# endif
+
+# undef weak_alias
+# define weak_alias(original, alias)
 #endif
+
+#include <sysdeps/i386/i586/stpcpy.S>
diff --git a/sysdeps/i386/i686/multiarch/stpcpy.S b/sysdeps/i386/i686/multiarch/stpcpy.S
deleted file mode 100644
index ee81ab6..0000000
--- a/sysdeps/i386/i686/multiarch/stpcpy.S
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Multiple versions of stpcpy
-   All versions must be listed in ifunc-impl-list.c.  */
-#define USE_AS_STPCPY
-#define STRCPY __stpcpy
-#include "strcpy.S"
-
-weak_alias (__stpcpy, stpcpy)
-libc_hidden_def (__stpcpy)
-libc_hidden_builtin_def (stpcpy)
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i686/multiarch/stpcpy.c
similarity index 61%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i686/multiarch/stpcpy.c
index d241522..32553b9 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i686/multiarch/stpcpy.c
@@ -1,7 +1,6 @@
-/* Multiple versions of strnlen
+/* Multiple versions of stpcpy.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,20 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
+# define stpcpy __redirect_stpcpy
+# define __stpcpy __redirect___stpcpy
+# define NO_MEMPCPY_STPCPY_REDIRECT
+# define __NO_STRING_INLINES
+# include <string.h>
+# undef stpcpy
+# undef __stpcpy
+
+# define SYMBOL_NAME stpcpy
+# include "ifunc-sse2-ssse3.h"
+
+libc_ifunc_redirected (__redirect_stpcpy, __stpcpy, IFUNC_SELECTOR ());
 
-weak_alias(__strnlen, strnlen)
+weak_alias (__stpcpy, stpcpy)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/memrchr.S b/sysdeps/i386/i686/multiarch/stpncpy-ia32.S
similarity index 61%
copy from sysdeps/i386/i686/multiarch/memrchr.S
copy to sysdeps/i386/i686/multiarch/stpncpy-ia32.S
index d4253a5..d1be1fc 100644
--- a/sysdeps/i386/i686/multiarch/memrchr.S
+++ b/sysdeps/i386/i686/multiarch/stpncpy-ia32.S
@@ -1,7 +1,6 @@
-/* Multiple versions of memrchr
+/* stpncpy optimized for i686.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,28 +17,21 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__memrchr)
-	.type	__memrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	3f
-
-	LOAD_FUNC_GOT_EAX (__memrchr_sse2)
-	ret
-
-2:	LOAD_FUNC_GOT_EAX (__memrchr_ia32)
-	ret
-
-3:	LOAD_FUNC_GOT_EAX (__memrchr_sse2_bsf)
-	ret
-END(__memrchr)
-
-weak_alias(__memrchr, memrchr)
+# define __stpncpy __stpncpy_ia32
+
+# ifdef SHARED
+#  undef libc_hidden_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_def(name) \
+	.globl __GI___stpncpy; __GI___stpncpy = __stpncpy
+
+# undef weak_alias
+# define weak_alias(original, alias)
+# endif
+
 #endif
+
+#include <sysdeps/i386/stpncpy.S>
diff --git a/sysdeps/i386/i686/multiarch/stpncpy.S b/sysdeps/i386/i686/multiarch/stpncpy.S
deleted file mode 100644
index 2698ca6..0000000
--- a/sysdeps/i386/i686/multiarch/stpncpy.S
+++ /dev/null
@@ -1,8 +0,0 @@
-/* Multiple versions of stpncpy
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCPY __stpncpy
-#define USE_AS_STPCPY
-#define USE_AS_STRNCPY
-#include "strcpy.S"
-
-weak_alias (__stpncpy, stpncpy)
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i686/multiarch/stpncpy.c
similarity index 64%
rename from sysdeps/i386/i686/multiarch/strnlen.S
rename to sysdeps/i386/i686/multiarch/stpncpy.c
index d241522..ec9b888 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i686/multiarch/stpncpy.c
@@ -1,7 +1,6 @@
-/* Multiple versions of strnlen
+/* Multiple versions of stpncpy.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,18 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
+# define stpncpy __redirect_stpncpy
+# define __stpncpy __redirect___stpncpy
+# include <string.h>
+# undef stpncpy
+# undef __stpncpy
+
+# define SYMBOL_NAME stpncpy
+# include "ifunc-sse2-ssse3.h"
+
+libc_ifunc_redirected (__redirect_stpncpy, __stpncpy, IFUNC_SELECTOR ());
 
-weak_alias(__strnlen, strnlen)
+weak_alias (__stpncpy, stpncpy)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/strcasecmp.S b/sysdeps/i386/i686/multiarch/strcasecmp.c
similarity index 62%
rename from sysdeps/i386/i686/multiarch/strcasecmp.S
rename to sysdeps/i386/i686/multiarch/strcasecmp.c
index ec59276..fd9fae3 100644
--- a/sysdeps/i386/i686/multiarch/strcasecmp.S
+++ b/sysdeps/i386/i686/multiarch/strcasecmp.c
@@ -1,6 +1,6 @@
-/* Entry point for multi-version x86 strcasecmp.
+/* Multiple versions of strcasecmp.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   Copyright (C) 2017 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
@@ -17,23 +17,19 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define strcasecmp __redirect_strcasecmp
+# define __strcasecmp __redirect___strcasecmp
+# include <string.h>
+# undef strcasecmp
+# undef __strcasecmp
 
-	.text
-ENTRY(__strcasecmp)
-	.type	__strcasecmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strcasecmp_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strcasecmp_ssse3)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_SSE4_2)
-	jnz	2f
-	LOAD_FUNC_GOT_EAX (__strcasecmp_sse4_2)
-2:	ret
-END(__strcasecmp)
+# define SYMBOL_NAME strcasecmp
+# include "ifunc-ssse3-sse4_2.h"
+
+libc_ifunc_redirected (__redirect_strcasecmp, __strcasecmp,
+		       IFUNC_SELECTOR ());
 
 weak_alias (__strcasecmp, strcasecmp)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strcasecmp_l.S b/sysdeps/i386/i686/multiarch/strcasecmp_l.S
deleted file mode 100644
index 711c09b..0000000
--- a/sysdeps/i386/i686/multiarch/strcasecmp_l.S
+++ /dev/null
@@ -1,7 +0,0 @@
-/* Multiple versions of strcasecmp_l
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCMP __strcasecmp_l
-#define USE_AS_STRCASECMP_L
-#include "strcmp.S"
-
-weak_alias (__strcasecmp_l, strcasecmp_l)
diff --git a/sysdeps/i386/i686/multiarch/wmemcmp.S b/sysdeps/i386/i686/multiarch/strcasecmp_l.c
similarity index 60%
rename from sysdeps/i386/i686/multiarch/wmemcmp.S
rename to sysdeps/i386/i686/multiarch/strcasecmp_l.c
index 1b9a54a..56f21a7 100644
--- a/sysdeps/i386/i686/multiarch/wmemcmp.S
+++ b/sysdeps/i386/i686/multiarch/strcasecmp_l.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wmemcmp
+/* Multiple versions of strcasecmp_l.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,23 +17,19 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define strcasecmp_l __redirect_strcasecmp_l
+# define __strcasecmp_l __redirect___strcasecmp_l
+# include <string.h>
+# undef strcasecmp_l
+# undef __strcasecmp_l
 
-/* Define multiple versions only for the definition in libc. */
+# define SYMBOL_NAME strcasecmp_l
+# include "ifunc-ssse3-sse4_2.h"
 
-#if IS_IN (libc)
-	.text
-ENTRY(wmemcmp)
-	.type	wmemcmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wmemcmp_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wmemcmp_ssse3)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wmemcmp_sse4_2)
-2:	ret
-END(wmemcmp)
+libc_ifunc_redirected (__redirect_strcasecmp_l, __strcasecmp_l,
+		       IFUNC_SELECTOR ());
+
+weak_alias (__strcasecmp_l, strcasecmp_l)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/strcat-ia32.S
similarity index 64%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/strcat-ia32.S
index 6ef9b6e..81d0c8d 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/strcat-ia32.S
@@ -1,7 +1,6 @@
-/* Multiple versions of wcslen
+/* strcat optimized for i686.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define strcat __strcat_ia32
 
-weak_alias(__wcslen, wcslen)
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_strcat; __GI_strcat = strcat
+# endif
 #endif
+
+#include <sysdeps/i386/strcat.S>
diff --git a/sysdeps/i386/i686/multiarch/strcat.S b/sysdeps/i386/i686/multiarch/strcat.S
deleted file mode 100644
index 8412cb6..0000000
--- a/sysdeps/i386/i686/multiarch/strcat.S
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Multiple versions of strcat
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#ifndef USE_AS_STRNCAT
-# ifndef STRCAT
-#  define STRCAT strcat
-# endif
-#endif
-
-#ifdef USE_AS_STRNCAT
-# define STRCAT_SSSE3	__strncat_ssse3
-# define STRCAT_SSE2		__strncat_sse2
-# define STRCAT_IA32		__strncat_ia32
-# define __GI_STRCAT		__GI_strncat
-#else
-# define STRCAT_SSSE3	__strcat_ssse3
-# define STRCAT_SSE2		__strcat_sse2
-# define STRCAT_IA32		__strcat_ia32
-# define __GI_STRCAT		__GI_strcat
-#endif
-
-
-/* Define multiple versions only for the definition in libc.  Don't
-   define multiple versions for strncat in static library since we
-   need strncat before the initialization happened.  */
-#if IS_IN (libc)
-
-	.text
-ENTRY(STRCAT)
-	.type	STRCAT, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (STRCAT_IA32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCAT_SSE2)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCAT_SSSE3)
-2:	ret
-END(STRCAT)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type STRCAT_IA32, @function; \
-	.align 16; \
-	.globl STRCAT_IA32; \
-	.hidden STRCAT_IA32; \
-	STRCAT_IA32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size STRCAT_IA32, .-STRCAT_IA32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* It doesn't make sense to send libc-internal strcat calls through a PLT.
-   The speedup we get from using SSSE3 instruction is likely eaten away
-   by the indirect call in the PLT.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_STRCAT; __GI_STRCAT = STRCAT_IA32
-#  undef libc_hidden_def
-#  define libc_hidden_def(name) \
-	.globl __GI___STRCAT; __GI___STRCAT = STRCAT_IA32
-
-# endif
-#endif
-
-#ifndef USE_AS_STRNCAT
-# include "../../strcat.S"
-#endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strcat.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strcat.c
index cf67333..f41cecf 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strcat.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strcat.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define strcat __redirect_strcat
+# include <string.h>
+# undef strcat
+
+# define SYMBOL_NAME strcat
+# include "ifunc-sse2-ssse3.h"
+
+libc_ifunc_redirected (__redirect_strcat, strcat, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/strchr-ia32.S
similarity index 59%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/strchr-ia32.S
index 6ef9b6e..4e55bf9 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/strchr-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcslen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strchr optimized for i686.
+   Copyright (C) 2017 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
@@ -18,20 +16,20 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define strchr __strchr_ia32
+
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_strchr; __GI_strchr = strchr
+# endif
 
-weak_alias(__wcslen, wcslen)
+# undef weak_alias
+# define weak_alias(original, alias)
 #endif
+
+#include <sysdeps/i386/i586/strchr.S>
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strchr.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strchr.c
index cf67333..2029250 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strchr.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strchr.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define strchr __redirect_strchr
+# include <string.h>
+# undef strchr
+
+# define SYMBOL_NAME strchr
+# include "ifunc-sse2-bsf.h"
+
+libc_ifunc_redirected (__redirect_strchr, strchr, IFUNC_SELECTOR ());
+
+weak_alias (strchr, index)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/strcmp-ia32.S
similarity index 64%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/strcmp-ia32.S
index 6ef9b6e..2e87f19 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/strcmp-ia32.S
@@ -1,7 +1,6 @@
-/* Multiple versions of wcslen
+/* strcmp optimized for i686.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define strcmp __strcmp_ia32
 
-weak_alias(__wcslen, wcslen)
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_strcmp; __GI_strcmp = strcmp
+# endif
 #endif
+
+#include <sysdeps/i386/i686/strcmp.S>
diff --git a/sysdeps/i386/i686/multiarch/strcmp.S b/sysdeps/i386/i686/multiarch/strcmp.S
deleted file mode 100644
index 56de25a..0000000
--- a/sysdeps/i386/i686/multiarch/strcmp.S
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Multiple versions of strcmp
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#ifdef USE_AS_STRNCMP
-# define STRCMP			strncmp
-# define __GI_STRCMP		__GI_strncmp
-# define __STRCMP_IA32		__strncmp_ia32
-# define __STRCMP_SSSE3		__strncmp_ssse3
-# define __STRCMP_SSE4_2	__strncmp_sse4_2
-#elif defined USE_AS_STRCASECMP_L
-# define STRCMP			__strcasecmp_l
-# define __GI_STRCMP		__GI_strcasecmp_l
-# define __STRCMP_IA32		__strcasecmp_l_ia32
-# define __STRCMP_SSSE3		__strcasecmp_l_ssse3
-# define __STRCMP_SSE4_2	__strcasecmp_l_sse4_2
-#elif defined USE_AS_STRNCASECMP_L
-# define STRCMP			__strncasecmp_l
-# define __GI_STRCMP		__GI_strncasecmp_l
-# define __STRCMP_IA32		__strncasecmp_l_ia32
-# define __STRCMP_SSSE3		__strncasecmp_l_ssse3
-# define __STRCMP_SSE4_2	__strncasecmp_l_sse4_2
-#else
-# define STRCMP			strcmp
-# define __GI_STRCMP		__GI_strcmp
-# define __STRCMP_IA32		__strcmp_ia32
-# define __STRCMP_SSSE3		__strcmp_ssse3
-# define __STRCMP_SSE4_2	__strcmp_sse4_2
-#endif
-
-/* Define multiple versions only for the definition in libc.  Don't
-   define multiple versions for strncmp in static library since we
-   need strncmp before the initialization happened.  */
-#if (defined SHARED || !defined USE_AS_STRNCMP) && IS_IN (libc)
-	.text
-ENTRY(STRCMP)
-	.type	STRCMP, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__STRCMP_IA32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__STRCMP_SSSE3)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_SSE4_2)
-	jnz	2f
-	LOAD_FUNC_GOT_EAX (__STRCMP_SSE4_2)
-2:	ret
-END(STRCMP)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __STRCMP_IA32, @function; \
-	.p2align 4; \
-	.globl __STRCMP_IA32; \
-	.hidden __STRCMP_IA32; \
-	__STRCMP_IA32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __STRCMP_IA32, .-__STRCMP_IA32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_STRCMP; __GI_STRCMP = __STRCMP_IA32
-# endif
-#endif
-
-#if !defined USE_AS_STRNCMP && !defined USE_AS_STRCASECMP_L \
-    && !defined USE_AS_STRNCASECMP_L
-# include "../strcmp.S"
-#endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strcmp.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strcmp.c
index cf67333..4388181 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strcmp.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strcmp.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define strcmp __redirect_strcmp
+# include <string.h>
+# undef strcmp
+
+# define SYMBOL_NAME strcmp
+# include "ifunc-ssse3-sse4_2.h"
+
+libc_ifunc_redirected (__redirect_strcmp, strcmp, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/strcpy-ia32.S
similarity index 64%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/strcpy-ia32.S
index 6ef9b6e..14205b8 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/strcpy-ia32.S
@@ -1,7 +1,6 @@
-/* Multiple versions of wcslen
+/* strcpy optimized for i686.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define strcpy __strcpy_ia32
 
-weak_alias(__wcslen, wcslen)
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_strcpy; __GI_strcpy = strcpy
+# endif
 #endif
+
+#include <sysdeps/i386/i586/strcpy.S>
diff --git a/sysdeps/i386/i686/multiarch/strcpy.S b/sysdeps/i386/i686/multiarch/strcpy.S
deleted file mode 100644
index ffbc03c..0000000
--- a/sysdeps/i386/i686/multiarch/strcpy.S
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Multiple versions of strcpy
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if !defined (USE_AS_STPCPY) && !defined (USE_AS_STRNCPY)
-# ifndef STRCPY
-#  define STRCPY strcpy
-# endif
-#endif
-
-#ifdef USE_AS_STPCPY
-# ifdef USE_AS_STRNCPY
-#  define STRCPY_SSSE3	__stpncpy_ssse3
-#  define STRCPY_SSE2		__stpncpy_sse2
-#  define STRCPY_IA32		__stpncpy_ia32
-#  define __GI_STRCPY		__GI_stpncpy
-#  define __GI___STRCPY		__GI___stpncpy
-# else
-#  define STRCPY_SSSE3	__stpcpy_ssse3
-#  define STRCPY_SSE2		__stpcpy_sse2
-#  define STRCPY_IA32		__stpcpy_ia32
-#  define __GI_STRCPY		__GI_stpcpy
-#  define __GI___STRCPY		__GI___stpcpy
-# endif
-#else
-# ifdef USE_AS_STRNCPY
-#  define STRCPY_SSSE3	__strncpy_ssse3
-#  define STRCPY_SSE2		__strncpy_sse2
-#  define STRCPY_IA32		__strncpy_ia32
-#  define __GI_STRCPY		__GI_strncpy
-# else
-#  define STRCPY_SSSE3	__strcpy_ssse3
-#  define STRCPY_SSE2		__strcpy_sse2
-#  define STRCPY_IA32		__strcpy_ia32
-#  define __GI_STRCPY		__GI_strcpy
-# endif
-#endif
-
-
-/* Define multiple versions only for the definition in libc.  Don't
-   define multiple versions for strncpy in static library since we
-   need strncpy before the initialization happened.  */
-#if IS_IN (libc)
-
-	.text
-ENTRY(STRCPY)
-	.type	STRCPY, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (STRCPY_IA32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCPY_SSE2)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCPY_SSSE3)
-2:	ret
-END(STRCPY)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type STRCPY_IA32, @function; \
-	.align 16; \
-	.globl STRCPY_IA32; \
-	.hidden STRCPY_IA32; \
-	STRCPY_IA32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size STRCPY_IA32, .-STRCPY_IA32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* It doesn't make sense to send libc-internal strcpy calls through a PLT.
-   The speedup we get from using SSSE3 instruction is likely eaten away
-   by the indirect call in the PLT.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_STRCPY; __GI_STRCPY = STRCPY_IA32
-#  undef libc_hidden_def
-#  define libc_hidden_def(name) \
-	.globl __GI___STRCPY; __GI___STRCPY = STRCPY_IA32
-
-# endif
-#endif
-
-#ifdef USE_AS_STPCPY
-# ifdef USE_AS_STRNCPY
-#  include "../../stpncpy.S"
-# else
-#  include "../../i586/stpcpy.S"
-# endif
-#else
-# ifndef USE_AS_STRNCPY
-#  include "../../i586/strcpy.S"
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strcpy.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strcpy.c
index cf67333..e36d174 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strcpy.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strcpy.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define strcpy __redirect_strcpy
+# include <string.h>
+# undef strcpy
+
+# define SYMBOL_NAME strcpy
+# include "ifunc-sse2-ssse3.h"
+
+libc_ifunc_redirected (__redirect_strcpy, strcpy, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/strcspn-ia32.S
similarity index 63%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/strcspn-ia32.S
index 6ef9b6e..483a38d 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/strcspn-ia32.S
@@ -1,7 +1,6 @@
-/* Multiple versions of wcslen
+/* strcspn optimized for i686.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define strcspn __strcspn_ia32
 
-weak_alias(__wcslen, wcslen)
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_strcspn; __GI_strcspn = strcspn
+# endif
 #endif
+
+#include <sysdeps/i386/strcspn.S>
diff --git a/sysdeps/i386/i686/multiarch/strcspn.S b/sysdeps/i386/i686/multiarch/strcspn.S
deleted file mode 100644
index 21e5093..0000000
--- a/sysdeps/i386/i686/multiarch/strcspn.S
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Multiple versions of strcspn
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2009-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <config.h>
-#include <sysdep.h>
-#include <init-arch.h>
-
-#ifdef USE_AS_STRPBRK
-#define STRCSPN_SSE42	__strpbrk_sse42
-#define STRCSPN_IA32	__strpbrk_ia32
-#define __GI_STRCSPN	__GI_strpbrk
-#else
-#ifndef STRCSPN
-#define STRCSPN		strcspn
-#define STRCSPN_SSE42	__strcspn_sse42
-#define STRCSPN_IA32	__strcspn_ia32
-#define __GI_STRCSPN	__GI_strcspn
-#endif
-#endif
-
-/* Define multiple versions only for the definition in libc.  Don't
-   define multiple versions for strpbrk in static library since we
-   need strpbrk before the initialization happened.  */
-#if (defined SHARED || !defined USE_AS_STRPBRK) && IS_IN (libc)
-	.text
-ENTRY(STRCSPN)
-	.type	STRCSPN, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (STRCSPN_IA32)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCSPN_SSE42)
-2:	ret
-END(STRCSPN)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type STRCSPN_IA32, @function; \
-	.globl STRCSPN_IA32; \
-	.p2align 4; \
-	STRCSPN_IA32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size STRCSPN_IA32, .-STRCSPN_IA32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_STRCSPN; __GI_STRCSPN = STRCSPN_IA32
-#endif
-
-#ifdef USE_AS_STRPBRK
-#include "../../strpbrk.S"
-#else
-#include "../../strcspn.S"
-#endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strcspn.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strcspn.c
index cf67333..3cf1aa8 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strcspn.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strcspn.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define strcspn __redirect_strcspn
+# include <string.h>
+# undef strcspn
+
+# define SYMBOL_NAME strcspn
+# include "ifunc-sse4_2.h"
+
+libc_ifunc_redirected (__redirect_strcspn, strcspn, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strlen-ia32.S
similarity index 61%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strlen-ia32.S
index cf67333..c511783 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strlen-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcsrchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strlen optimized for i686.
+   Copyright (C) 2017 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
@@ -18,18 +16,15 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#if defined SHARED && IS_IN (libc)
+# define strlen __strlen_ia32
 
-#if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+# define libc_hidden_builtin_def(name) \
+	.globl __GI_strlen; __GI_strlen = strlen
 #endif
+
+#include <sysdeps/i386/i586/strlen.S>
diff --git a/sysdeps/i386/i686/multiarch/strlen.S b/sysdeps/i386/i686/multiarch/strlen.S
deleted file mode 100644
index 77cf6bc..0000000
--- a/sysdeps/i386/i686/multiarch/strlen.S
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Multiple versions of strlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2009-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc and for the
-   DSO.  In static binaries, we need strlen before the initialization
-   happened.  */
-#if defined SHARED && IS_IN (libc)
-	.text
-ENTRY(strlen)
-	.type	strlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strlen_sse2_bsf)
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strlen_sse2)
-2:	ret
-END(strlen)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strlen_ia32, @function; \
-	.globl __strlen_ia32; \
-	.p2align 4; \
-	__strlen_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strlen_ia32, .-__strlen_ia32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_strlen; __GI_strlen = __strlen_ia32
-#endif
-
-#include "../../i586/strlen.S"
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strlen.c
similarity index 66%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strlen.c
index cf67333..2968bcc 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strlen.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strlen.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+/* Define multiple versions only for the definition in libc.so.  */
+#if defined SHARED && IS_IN (libc)
+# define strlen __redirect_strlen
+# include <string.h>
+# undef strlen
 
-#if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define SYMBOL_NAME strlen
+# include "ifunc-sse2-bsf.h"
+
+libc_ifunc_redirected (__redirect_strlen, strlen, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/strncase.S b/sysdeps/i386/i686/multiarch/strncase.c
similarity index 61%
rename from sysdeps/i386/i686/multiarch/strncase.S
rename to sysdeps/i386/i686/multiarch/strncase.c
index a56e63a..68922e4 100644
--- a/sysdeps/i386/i686/multiarch/strncase.S
+++ b/sysdeps/i386/i686/multiarch/strncase.c
@@ -1,6 +1,6 @@
-/* Entry point for multi-version x86 strncasecmp.
+/* Multiple versions of strncasecmp.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   Copyright (C) 2017 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
@@ -17,23 +17,19 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define strncasecmp __redirect_strncasecmp
+# define __strncasecmp __redirect___strncasecmp
+# include <string.h>
+# undef strncasecmp
+# undef __strncasecmp
 
-	.text
-ENTRY(__strncasecmp)
-	.type	__strncasecmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strncasecmp_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strncasecmp_ssse3)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_SSE4_2)
-	jnz	2f
-	LOAD_FUNC_GOT_EAX (__strncasecmp_sse4_2)
-2:	ret
-END(__strncasecmp)
+# define SYMBOL_NAME strncasecmp
+# include "ifunc-ssse3-sse4_2.h"
+
+libc_ifunc_redirected (__redirect_strncasecmp, __strncasecmp,
+		       IFUNC_SELECTOR ());
 
 weak_alias (__strncasecmp, strncasecmp)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strncase_l.S b/sysdeps/i386/i686/multiarch/strncase_l.S
deleted file mode 100644
index 8a74ee8..0000000
--- a/sysdeps/i386/i686/multiarch/strncase_l.S
+++ /dev/null
@@ -1,7 +0,0 @@
-/* Multiple versions of strncasecmp_l
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCMP __strncasecmp_l
-#define USE_AS_STRNCASECMP_L
-#include "strcmp.S"
-
-weak_alias (__strncasecmp_l, strncasecmp_l)
diff --git a/sysdeps/i386/i686/multiarch/memrchr.S b/sysdeps/i386/i686/multiarch/strncase_l.c
similarity index 60%
copy from sysdeps/i386/i686/multiarch/memrchr.S
copy to sysdeps/i386/i686/multiarch/strncase_l.c
index d4253a5..ab25cb9 100644
--- a/sysdeps/i386/i686/multiarch/memrchr.S
+++ b/sysdeps/i386/i686/multiarch/strncase_l.c
@@ -1,7 +1,6 @@
-/* Multiple versions of memrchr
+/* Multiple versions of strncasecmp_l.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,28 +17,19 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(__memrchr)
-	.type	__memrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	3f
-
-	LOAD_FUNC_GOT_EAX (__memrchr_sse2)
-	ret
+# define strncasecmp_l __redirect_strncasecmp_l
+# define __strncasecmp_l __redirect___strncasecmp_l
+# include <string.h>
+# undef strncasecmp_l
+# undef __strncasecmp_l
 
-2:	LOAD_FUNC_GOT_EAX (__memrchr_ia32)
-	ret
+# define SYMBOL_NAME strncasecmp_l
+# include "ifunc-ssse3-sse4_2.h"
 
-3:	LOAD_FUNC_GOT_EAX (__memrchr_sse2_bsf)
-	ret
-END(__memrchr)
+libc_ifunc_redirected (__redirect_strncasecmp_l, __strncasecmp_l,
+		       IFUNC_SELECTOR ());
 
-weak_alias(__memrchr, memrchr)
+weak_alias (__strncasecmp_l, strncasecmp_l)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/strncat.S b/sysdeps/i386/i686/multiarch/strncat.S
deleted file mode 100644
index 5c1bf41..0000000
--- a/sysdeps/i386/i686/multiarch/strncat.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Multiple versions of strncat
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCAT strncat
-#define USE_AS_STRNCAT
-#include "strcat.S"
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strncat.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strncat.c
index cf67333..5acad3d 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strncat.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strcat.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define strncat __redirect_strncat
+# include <string.h>
+# undef strncat
+
+# define SYMBOL_NAME strncat
+# include "ifunc-sse2-ssse3.h"
+
+libc_ifunc_redirected (__redirect_strncat, strncat, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/strncmp.S b/sysdeps/i386/i686/multiarch/strncmp.S
deleted file mode 100644
index 150d478..0000000
--- a/sysdeps/i386/i686/multiarch/strncmp.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Multiple versions of strncmp
-   All versions must be listed in ifunc-impl-list.c.  */
-#define USE_AS_STRNCMP
-#define STRCMP	strncmp
-#include "strcmp.S"
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strncmp.c
similarity index 66%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strncmp.c
index cf67333..3fea85f 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strncmp.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strncmp.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+/* Define multiple versions only for the definition in libc.so.  */
+#if defined SHARED && IS_IN (libc)
+# define strncmp __redirect_strncmp
+# include <string.h>
+# undef strncmp
 
-#if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define SYMBOL_NAME strncmp
+# include "ifunc-ssse3-sse4_2.h"
+
+libc_ifunc_redirected (__redirect_strncmp, strncmp, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/strncpy.S b/sysdeps/i386/i686/multiarch/strncpy.S
deleted file mode 100644
index 9c257ef..0000000
--- a/sysdeps/i386/i686/multiarch/strncpy.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Multiple versions of strncpy
-   All versions must be listed in ifunc-impl-list.c.  */
-#define USE_AS_STRNCPY
-#define STRCPY strncpy
-#include "strcpy.S"
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strncpy.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strncpy.c
index cf67333..24404f6 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strncpy.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strncpy.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,15 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define _HAVE_STRING_ARCH_strncpy 1
+# define strncpy __redirect_strncpy
+# include <string.h>
+# undef strncpy
+
+# define SYMBOL_NAME strncpy
+# include "ifunc-sse2-ssse3.h"
+
+libc_ifunc_redirected (__redirect_strncpy, strncpy, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcscpy.S b/sysdeps/i386/i686/multiarch/strnlen.c
similarity index 64%
rename from sysdeps/i386/i686/multiarch/wcscpy.S
rename to sysdeps/i386/i686/multiarch/strnlen.c
index cfc97dd..83930bc 100644
--- a/sysdeps/i386/i686/multiarch/wcscpy.S
+++ b/sysdeps/i386/i686/multiarch/strnlen.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcscpy
+/* Multiple versions of strnlen.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,19 +17,18 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc. */
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcscpy)
-	.type	wcscpy, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcscpy_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcscpy_ssse3)
-2:	ret
-END(wcscpy)
+# define strnlen __redirect_strnlen
+# define __strnlen __redirect___strnlen
+# include <string.h>
+# undef __strnlen
+# undef strnlen
+
+# define SYMBOL_NAME strnlen
+# include "ifunc-sse2.h"
+
+libc_ifunc_redirected (__redirect_strnlen, __strnlen, IFUNC_SELECTOR ());
+
+weak_alias (__strnlen, strnlen);
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/strpbrk-ia32.S
similarity index 63%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/strpbrk-ia32.S
index 6ef9b6e..506043f 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/strpbrk-ia32.S
@@ -1,7 +1,6 @@
-/* Multiple versions of wcslen
+/* strpbrk optimized for i686.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define strpbrk __strpbrk_ia32
 
-weak_alias(__wcslen, wcslen)
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_strpbrk; __GI_strpbrk = strpbrk
+# endif
 #endif
+
+#include <sysdeps/i386/strpbrk.S>
diff --git a/sysdeps/i386/i686/multiarch/strpbrk.S b/sysdeps/i386/i686/multiarch/strpbrk.S
deleted file mode 100644
index 7201d63..0000000
--- a/sysdeps/i386/i686/multiarch/strpbrk.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Multiple versions of strpbrk
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCSPN strpbrk
-#define USE_AS_STRPBRK
-#include "strcspn.S"
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strpbrk.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strpbrk.c
index cf67333..50bbb16 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strpbrk.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strpbrk.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define strpbrk __redirect_strpbrk
+# include <string.h>
+# undef strpbrk
+
+# define SYMBOL_NAME strpbrk
+# include "ifunc-sse4_2.h"
+
+libc_ifunc_redirected (__redirect_strpbrk, strpbrk, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/strrchr-ia32.S
similarity index 59%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/strrchr-ia32.S
index 6ef9b6e..a0effaa 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/strrchr-ia32.S
@@ -1,7 +1,5 @@
-/* Multiple versions of wcslen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strrchr optimized for i686.
+   Copyright (C) 2017 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
@@ -18,20 +16,20 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define strrchr __strrchr_ia32
+
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_strrchr; __GI_strrchr = strrchr
+# endif
 
-weak_alias(__wcslen, wcslen)
+# undef weak_alias
+# define weak_alias(original, alias)
 #endif
+
+#include <sysdeps/i386/strrchr.S>
diff --git a/sysdeps/i386/i686/multiarch/strrchr.S b/sysdeps/i386/i686/multiarch/strrchr.S
deleted file mode 100644
index d9281ea..0000000
--- a/sysdeps/i386/i686/multiarch/strrchr.S
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Multiple versions of strrchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(strrchr)
-	.type	strrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strrchr_sse2_bsf)
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strrchr_sse2)
-2:	ret
-END(strrchr)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strrchr_ia32, @function; \
-	.globl __strrchr_ia32; \
-	.p2align 4; \
-	__strrchr_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strrchr_ia32, .-__strrchr_ia32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_strrchr; __GI_strrchr = __strrchr_ia32
-#endif
-
-#include "../../strrchr.S"
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strrchr.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strrchr.c
index cf67333..ffacd0e 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strrchr.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strrchr.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define strrchr __redirect_strrchr
+# include <string.h>
+# undef strrchr
+
+# define SYMBOL_NAME strrchr
+# include "ifunc-sse2-bsf.h"
+
+libc_ifunc_redirected (__redirect_strrchr, strrchr, IFUNC_SELECTOR ());
+
+weak_alias (strrchr, rindex)
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/strspn-ia32.S
similarity index 64%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/strspn-ia32.S
index 6ef9b6e..d2b9beb 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/strspn-ia32.S
@@ -1,7 +1,6 @@
-/* Multiple versions of wcslen
+/* strspn optimized for i686.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define strspn __strspn_ia32
 
-weak_alias(__wcslen, wcslen)
+# ifdef SHARED
+#  undef libc_hidden_builtin_def
+/* IFUNC doesn't work with the hidden functions in shared library since
+   they will be called without setting up EBX needed for PLT which is
+   used by IFUNC.  */
+#  define libc_hidden_builtin_def(name) \
+	.globl __GI_strspn; __GI_strspn = strspn
+# endif
 #endif
+
+#include <sysdeps/i386/strspn.S>
diff --git a/sysdeps/i386/i686/multiarch/strspn.S b/sysdeps/i386/i686/multiarch/strspn.S
deleted file mode 100644
index 1269062..0000000
--- a/sysdeps/i386/i686/multiarch/strspn.S
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Multiple versions of strspn
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2009-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <config.h>
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc.  */
-#if IS_IN (libc)
-	.text
-ENTRY(strspn)
-	.type	strspn, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strspn_ia32)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strspn_sse42)
-2:	ret
-END(strspn)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strspn_ia32, @function; \
-	.globl __strspn_ia32; \
-	.p2align 4; \
-__strspn_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strspn_ia32, .-__strspn_ia32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_strspn; __GI_strspn = __strspn_ia32
-#endif
-
-#include "../../strspn.S"
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/strspn.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/strspn.c
index cf67333..e1a86df 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/strspn.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of strspn.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define strspn __redirect_strspn
+# include <string.h>
+# undef strspn
+
+# define SYMBOL_NAME strspn
+# include "ifunc-sse4_2.h"
+
+libc_ifunc_redirected (__redirect_strspn, strspn, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/wcschr.c
similarity index 65%
copy from sysdeps/i386/i686/multiarch/wcslen.S
copy to sysdeps/i386/i686/multiarch/wcschr.c
index 6ef9b6e..2dfd318 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/wcschr.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcslen
+/* Multiple versions of wcschr.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define wcschr __redirect_wcschr
+# define __wcschr __redirect___wcschr
+# include <wchar.h>
+# undef wcschr
+# undef __wcschr
+
+# define SYMBOL_NAME wcschr
+# include "ifunc-sse2.h"
 
-weak_alias(__wcslen, wcslen)
+libc_ifunc_redirected (__redirect_wcschr, __wcschr, IFUNC_SELECTOR ());
+weak_alias (__wcschr, wcschr);
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/wcscmp.c
similarity index 65%
rename from sysdeps/i386/i686/multiarch/wcslen.S
rename to sysdeps/i386/i686/multiarch/wcscmp.c
index 6ef9b6e..e14bd73 100644
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ b/sysdeps/i386/i686/multiarch/wcscmp.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcslen
+/* Multiple versions of wcscmp.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,20 +17,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
+# define wcscmp __redirect_wcscmp
+# define __wcscmp __redirect___wcscmp
+# include <wchar.h>
+# undef wcscmp
+# undef __wcscmp
+
+# define SYMBOL_NAME wcscmp
+# include "ifunc-sse2.h"
 
-weak_alias(__wcslen, wcslen)
+libc_ifunc_redirected (__redirect_wcscmp, __wcscmp, IFUNC_SELECTOR ());
+weak_alias (__wcscmp, wcscmp);
 #endif
diff --git a/sysdeps/i386/i686/multiarch/memrchr.S b/sysdeps/i386/i686/multiarch/wcscpy.c
similarity index 55%
rename from sysdeps/i386/i686/multiarch/memrchr.S
rename to sysdeps/i386/i686/multiarch/wcscpy.c
index d4253a5..bc17f36 100644
--- a/sysdeps/i386/i686/multiarch/memrchr.S
+++ b/sysdeps/i386/i686/multiarch/wcscpy.c
@@ -1,7 +1,6 @@
-/* Multiple versions of memrchr
+/* Multiple versions of wcscpy.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,28 +17,28 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define wcscpy __redirect_wcscpy
+# include <wchar.h>
+# undef wcscpy
+
+# define SYMBOL_NAME wcscpy
 #include <init-arch.h>
 
-#if IS_IN (libc)
-	.text
-ENTRY(__memrchr)
-	.type	__memrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	3f
-
-	LOAD_FUNC_GOT_EAX (__memrchr_sse2)
-	ret
-
-2:	LOAD_FUNC_GOT_EAX (__memrchr_ia32)
-	ret
-
-3:	LOAD_FUNC_GOT_EAX (__memrchr_sse2_bsf)
-	ret
-END(__memrchr)
-
-weak_alias(__memrchr, memrchr)
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ia32) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (ssse3) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
+
+  if (CPU_FEATURES_CPU_P (cpu_features, SSSE3))
+    return OPTIMIZE (ssse3);
+
+  return OPTIMIZE (ia32);
+}
+
+libc_ifunc_redirected (__redirect_wcscpy, wcscpy, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/wcslen.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/wcslen.c
index cf67333..4870e64 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/wcslen.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of wcslen.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,15 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define __wcslen __redirect_wcslen
+# include <wchar.h>
+# undef __wcslen
+
+# define SYMBOL_NAME wcslen
+# include "ifunc-sse2.h"
+
+libc_ifunc_redirected (__redirect_wcslen, __wcslen, IFUNC_SELECTOR ());
+weak_alias (__wcslen, wcslen);
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/wcsrchr.c
similarity index 67%
copy from sysdeps/i386/i686/multiarch/wcsrchr.S
copy to sysdeps/i386/i686/multiarch/wcsrchr.c
index cf67333..3169feb 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/wcsrchr.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of wcsrchr.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define wcsrchr __redirect_wcsrchr
+# include <wchar.h>
+# undef wcsrchr
+
+# define SYMBOL_NAME wcsrchr
+# include "ifunc-sse2.h"
+
+libc_ifunc_redirected (__redirect_wcsrchr, wcsrchr, IFUNC_SELECTOR ());
 #endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/wmemcmp.c
similarity index 67%
rename from sysdeps/i386/i686/multiarch/wcsrchr.S
rename to sysdeps/i386/i686/multiarch/wmemcmp.c
index cf67333..ca61408 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ b/sysdeps/i386/i686/multiarch/wmemcmp.c
@@ -1,7 +1,6 @@
-/* Multiple versions of wcsrchr
+/* Multiple versions of wmemcmp.
    All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+   Copyright (C) 2017 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
@@ -18,18 +17,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
+/* Define multiple versions only for the definition in libc.  */
 #if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
+# define wmemcmp __redirect_wmemcmp
+# include <wchar.h>
+# undef wmemcmp
+
+# define SYMBOL_NAME wmemcmp
+# include "ifunc-ssse3-sse4_2.h"
+
+libc_ifunc_redirected (__redirect_wmemcmp, wmemcmp, IFUNC_SELECTOR ());
 #endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f347d27a43c3be3f222c96720c516f5cd23f93de

commit f347d27a43c3be3f222c96720c516f5cd23f93de
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Jul 18 15:35:30 2017 -0700

    x86-64: Convert libmathvec IFUNC selectors to C

diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile
index 86ddde3..f9ceb09 100644
--- a/sysdeps/x86_64/fpu/multiarch/Makefile
+++ b/sysdeps/x86_64/fpu/multiarch/Makefile
@@ -70,5 +70,35 @@ libmvec-sysdep_routines += svml_d_cos2_core_sse4 svml_d_cos4_core_avx2 \
 			   svml_d_pow4_core_avx2 svml_d_pow8_core_avx512 \
 			   svml_s_powf4_core_sse4 svml_s_powf8_core_avx2 \
 			   svml_s_powf16_core_avx512 svml_s_sincosf4_core_sse4 \
-			   svml_s_sincosf8_core_avx2 svml_s_sincosf16_core_avx512
+			   svml_s_sincosf8_core_avx2 \
+			   svml_s_sincosf16_core_avx512 \
+			   svml_d_cos2_core-sse2 svml_d_cos4_core-sse \
+			   svml_d_cos8_core-avx2 svml_d_exp2_core-sse2 \
+			   svml_d_exp4_core-sse svml_d_exp8_core-avx2 \
+			   svml_d_log2_core-sse2 svml_d_log4_core-sse \
+			   svml_d_log8_core-avx2 svml_d_pow2_core-sse2 \
+			   svml_d_pow4_core-sse svml_d_pow8_core-avx2 \
+			   svml_d_sin2_core-sse2 svml_d_sin4_core-sse \
+			   svml_d_sin8_core-avx2 \
+			   svml_d_sincos2_core-sse2 \
+			   svml_d_sincos4_core-sse \
+			   svml_d_sincos8_core-avx2 \
+			   svml_s_cosf16_core-avx2 \
+			   svml_s_cosf4_core-sse2 \
+			   svml_s_cosf8_core-sse \
+			   svml_s_expf16_core-avx2 \
+			   svml_s_expf4_core-sse2 \
+			   svml_s_expf8_core-sse \
+			   svml_s_logf16_core-avx2 \
+			   svml_s_logf4_core-sse2 \
+			   svml_s_logf8_core-sse \
+			   svml_s_powf16_core-avx2 \
+			   svml_s_powf4_core-sse2 \
+			   svml_s_powf8_core-sse \
+			   svml_s_sincosf16_core-avx2 \
+			   svml_s_sincosf4_core-sse2 \
+			   svml_s_sincosf8_core-sse \
+			   svml_s_sinf16_core-avx2 \
+			   svml_s_sinf4_core-sse2 \
+			   svml_s_sinf8_core-sse
 endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-avx2.h
similarity index 56%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-avx2.h
index 5a17e11..a43d4c5 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-avx2.h
@@ -1,5 +1,6 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Common definition for libmathvec ifunc selections optimized with
+   AVX2.
+   Copyright (C) 2017 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
@@ -16,21 +17,22 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
 #include <init-arch.h>
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
-
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#undef PASTER2
+#define PASTER2(x,y)	x##_##y
+
+extern void REDIRECT_NAME (void);
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse_wrapper) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
+
+  if (CPU_FEATURES_ARCH_P (cpu_features, AVX2_Usable))
+    return OPTIMIZE (avx2);
+
+  return OPTIMIZE (sse_wrapper);
+}
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-avx512.h
similarity index 50%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-avx512.h
index 5a17e11..1857e1f 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-avx512.h
@@ -1,5 +1,6 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Common definition for libmathvec ifunc selections optimized with
+   AVX512.
+   Copyright (C) 2017 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
@@ -16,21 +17,26 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
 #include <init-arch.h>
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
-
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#undef PASTER2
+#define PASTER2(x,y)	x##_##y
+
+extern void REDIRECT_NAME (void);
+extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_wrapper) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (knl) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (skx) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
+
+  if (CPU_FEATURES_ARCH_P (cpu_features, AVX512DQ_Usable))
+    return OPTIMIZE (skx);
+
+  if (CPU_FEATURES_ARCH_P (cpu_features, AVX512F_Usable))
+    return OPTIMIZE (knl);
+
+  return OPTIMIZE (avx2_wrapper);
+}
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-sse4_1.h
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-sse4_1.h
index 5a17e11..fcd0e68 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-sse4_1.h
@@ -1,5 +1,6 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Common definition for libmathvec ifunc selections optimized with
+   SSE4.1.
+   Copyright (C) 2017 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
@@ -16,21 +17,22 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
 #include <init-arch.h>
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
-
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#undef PASTER2
+#define PASTER2(x,y)	x##_##y
+
+extern void REDIRECT_NAME (void);
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse4) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
+
+  if (CPU_FEATURES_CPU_P (cpu_features, SSE4_1))
+    return OPTIMIZE (sse4);
+
+  return OPTIMIZE (sse2);
+}
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core-sse2.S
similarity index 66%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core-sse2.S
index b209492..82601e7 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized cos, vector length is 2.
+/* SSE2 version of vectorized cos, vector length is 2.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN2v_cos)
-        .type   _ZGVbN2v_cos, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_cos_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_cos_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_cos)
-libmvec_hidden_def (_ZGVbN2v_cos)
-
 #define _ZGVbN2v_cos _ZGVbN2v_cos_sse2
 #include "../svml_d_cos2_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core.c
similarity index 61%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core.c
index b209492..f5645c7 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_cos2_core.c
@@ -1,5 +1,5 @@
 /* Multiple versions of vectorized cos, vector length is 2.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+   Copyright (C) 2017 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
@@ -16,21 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN2v_cos
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN2v_cos)
-        .type   _ZGVbN2v_cos, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_cos_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_cos_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_cos)
-libmvec_hidden_def (_ZGVbN2v_cos)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_cos _ZGVbN2v_cos_sse2
-#include "../svml_d_cos2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN2v_cos, __GI__ZGVbN2v_cos, __redirect__ZGVbN2v_cos)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core-sse.S
similarity index 66%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core-sse.S
index ff382e9..cd928f2 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized cos, vector length is 4.
+/* SSE version of vectorized cos, vector length is 4.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN4v_cos)
-        .type   _ZGVdN4v_cos, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN4v_cos_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN4v_cos_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN4v_cos)
-libmvec_hidden_def (_ZGVdN4v_cos)
-
 #define _ZGVdN4v_cos _ZGVdN4v_cos_sse_wrapper
 #include "../svml_d_cos4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core.c
similarity index 60%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core.c
index ff382e9..7b29e25 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_cos4_core.c
@@ -1,5 +1,5 @@
 /* Multiple versions of vectorized cos, vector length is 4.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+   Copyright (C) 2017 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
@@ -16,21 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN4v_cos
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVdN4v_cos)
-        .type   _ZGVdN4v_cos, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN4v_cos_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN4v_cos_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN4v_cos)
-libmvec_hidden_def (_ZGVdN4v_cos)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVdN4v_cos _ZGVdN4v_cos_sse_wrapper
-#include "../svml_d_cos4_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN4v_cos, __GI__ZGVdN4v_cos, __redirect__ZGVdN4v_cos)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core-avx2.S
similarity index 63%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core-avx2.S
index 46d35a2..b4c8ae2 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized cos, vector length is 8.
+/* AVX2 version of vectorized cos, vector length is 8.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,22 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVeN8v_cos)
-        .type   _ZGVeN8v_cos, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-1:      leaq    _ZGVeN8v_cos_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN8v_cos_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN8v_cos_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN8v_cos)
-
 #define _ZGVeN8v_cos _ZGVeN8v_cos_avx2_wrapper
 #include "../svml_d_cos8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core.c
similarity index 58%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core.c
index 46d35a2..6d30baa 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core.c
@@ -1,5 +1,5 @@
 /* Multiple versions of vectorized cos, vector length is 8.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+   Copyright (C) 2017 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
@@ -16,22 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN8v_cos
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVeN8v_cos)
-        .type   _ZGVeN8v_cos, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-1:      leaq    _ZGVeN8v_cos_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN8v_cos_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN8v_cos_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN8v_cos)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVeN8v_cos _ZGVeN8v_cos_avx2_wrapper
-#include "../svml_d_cos8_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN8v_cos, __GI__ZGVeN8v_cos, __redirect__ZGVeN8v_cos)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core-sse2.S
similarity index 68%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core-sse2.S
index 5a17e11..a66b82c 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized exp.
+/* SSE2 version of vectorized exp.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
-
 #define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
 #include "../svml_d_exp2_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.c
index 5a17e11..e24758d 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized exp, vector length is 2.
+   Copyright (C) 2017 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
@@ -16,21 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN2v_exp
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN2v_exp, __GI__ZGVbN2v_exp, __redirect__ZGVbN2v_exp)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_exp4_core-sse.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_exp4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_exp4_core-sse.S
index b994a79..613fae1 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_exp4_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized exp.
+/* SSE version of vectorized exp.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN4v_exp)
-        .type   _ZGVdN4v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN4v_exp_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN4v_exp_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN4v_exp)
-libmvec_hidden_def (_ZGVdN4v_exp)
-
 #define _ZGVdN4v_exp _ZGVdN4v_exp_sse_wrapper
 #include "../svml_d_exp4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_exp4_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_exp4_core.c
index 5a17e11..d3a9d87 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_exp4_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized exp, vector length is 4.
+   Copyright (C) 2017 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
@@ -16,21 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN4v_exp
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN4v_exp, __GI__ZGVdN4v_exp, __redirect__ZGVdN4v_exp)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_exp8_core-avx2.S
similarity index 64%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_exp8_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_exp8_core-avx2.S
index 6189080..9b95236 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_exp8_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized exp.
+/* AVX2 version of vectorized exp.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,22 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVeN8v_exp)
-        .type   _ZGVeN8v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVeN8v_exp_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN8v_exp_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN8v_exp_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN8v_exp)
-
 #define _ZGVeN8v_exp _ZGVeN8v_exp_avx2_wrapper
 #include "../svml_d_exp8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_exp8_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_exp8_core.c
index 5a17e11..cf8cd50 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_exp8_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized exp, vector length is 8.
+   Copyright (C) 2017 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
@@ -16,21 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN8v_exp
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN8v_exp, __GI__ZGVeN8v_exp, __redirect__ZGVeN8v_exp)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_log2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_log2_core-sse2.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_log2_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_log2_core-sse2.S
index 5097add..a8bffcc 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_log2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_log2_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized log.
+/* SSE2 version of vectorized log.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-        .text
-ENTRY (_ZGVbN2v_log)
-        .type   _ZGVbN2v_log, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_log_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_log_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_log)
-libmvec_hidden_def (_ZGVbN2v_log)
-
 #define _ZGVbN2v_log _ZGVbN2v_log_sse2
 #include "../svml_d_log2_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_log2_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_log2_core.c
index 5a17e11..2fcc08a 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_log2_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized log, vector length is 2.
+   Copyright (C) 2017 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
@@ -16,21 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN2v_log
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN2v_log, __GI__ZGVbN2v_log, __redirect__ZGVbN2v_log)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_log4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_log4_core-sse.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_log4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_log4_core-sse.S
index 1e9a2f4..0760b04 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_log4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_log4_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized log.
+/* SSE version of vectorized log.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN4v_log)
-        .type   _ZGVdN4v_log, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN4v_log_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN4v_log_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN4v_log)
-libmvec_hidden_def (_ZGVdN4v_log)
-
 #define _ZGVdN4v_log _ZGVdN4v_log_sse_wrapper
 #include "../svml_d_log4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_log4_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_log4_core.c
index 5a17e11..1756978 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_log4_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized log, vector length is 4.
+   Copyright (C) 2017 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
@@ -16,21 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN4v_log
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN4v_log, __GI__ZGVdN4v_log, __redirect__ZGVdN4v_log)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core-avx2.S
similarity index 64%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_log8_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_log8_core-avx2.S
index 43f572d..af3229f 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized log.
+/* AVX2 version of vectorized log.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,22 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVeN8v_log)
-        .type   _ZGVeN8v_log, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVeN8v_log_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN8v_log_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN8v_log_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN8v_log)
-
 #define _ZGVeN8v_log _ZGVeN8v_log_avx2_wrapper
 #include "../svml_d_log8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_log8_core.c
index 5a17e11..1d9864c 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized log, vector length is 8.
+   Copyright (C) 2017 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
@@ -16,21 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN8v_log
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN8v_log, __GI__ZGVeN8v_log, __redirect__ZGVeN8v_log)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_pow2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_pow2_core-sse2.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_pow2_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_pow2_core-sse2.S
index adb0872..2e8d40b 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_pow2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_pow2_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized pow.
+/* SSE2 version of vectorized pow.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN2vv_pow)
-        .type   _ZGVbN2vv_pow, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2vv_pow_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2vv_pow_sse2(%rip), %rax
-        ret
-END (_ZGVbN2vv_pow)
-libmvec_hidden_def (_ZGVbN2vv_pow)
-
 #define _ZGVbN2vv_pow _ZGVbN2vv_pow_sse2
 #include "../svml_d_pow2_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_pow2_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_pow2_core.c
index 5a17e11..bc72a77 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_pow2_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized pow, vector length is 2.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN2vv_pow
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN2vv_pow, __GI__ZGVbN2vv_pow,
+	       __redirect__ZGVbN2vv_pow)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_pow4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_pow4_core-sse.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_pow4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_pow4_core-sse.S
index eea8af6..7f17a7c 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_pow4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_pow4_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized pow.
+/* SSE version of vectorized pow.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN4vv_pow)
-        .type   _ZGVdN4vv_pow, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN4vv_pow_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN4vv_pow_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN4vv_pow)
-libmvec_hidden_def (_ZGVdN4vv_pow)
-
 #define _ZGVdN4vv_pow _ZGVdN4vv_pow_sse_wrapper
 #include "../svml_d_pow4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_pow4_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_pow4_core.c
index 5a17e11..f4b4db0 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_pow4_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized pow, vector length is 4.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN4vv_pow
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN4vv_pow, __GI__ZGVdN4vv_pow,
+	       __redirect__ZGVdN4vv_pow)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_pow8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_pow8_core-avx2.S
similarity index 64%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_pow8_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_pow8_core-avx2.S
index 68f12b2..02a4bdd 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_pow8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_pow8_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized pow.
+/* AVX2 version of vectorized pow.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,22 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVeN8vv_pow)
-        .type   _ZGVeN8vv_pow, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVeN8vv_pow_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN8vv_pow_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN8vv_pow_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN8vv_pow)
-
 #define _ZGVeN8vv_pow _ZGVeN8vv_pow_avx2_wrapper
 #include "../svml_d_pow8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_pow8_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_pow8_core.c
index 5a17e11..178f581 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_pow8_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized pow, vector length is 8.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN8vv_pow
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN8vv_pow, __GI__ZGVeN8vv_pow,
+	       __redirect__ZGVeN8vv_pow)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sin2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sin2_core-sse2.S
similarity index 68%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_sin2_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_sin2_core-sse2.S
index e35654b..9b49c3c 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sin2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sin2_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized sin.
+/* SSE2 version of vectorized sin.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN2v_sin)
-        .type   _ZGVbN2v_sin, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_sin_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_sin_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_sin)
-libmvec_hidden_def (_ZGVbN2v_sin)
-
 #define _ZGVbN2v_sin _ZGVbN2v_sin_sse2
 #include "../svml_d_sin2_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sin2_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_sin2_core.c
index 5a17e11..a0995e7 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sin2_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sin, vector length is 2.
+   Copyright (C) 2017 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
@@ -16,21 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN2v_sin
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN2v_sin, __GI__ZGVbN2v_sin, __redirect__ZGVbN2v_sin)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core-sse.S
similarity index 66%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core-sse.S
index f4482d3..0f27cef 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized sin, vector length is 4.
+/* SSE version of vectorized sin, vector length is 4.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN4v_sin)
-        .type   _ZGVdN4v_sin, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN4v_sin_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN4v_sin_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN4v_sin)
-libmvec_hidden_def (_ZGVdN4v_sin)
-
 #define _ZGVdN4v_sin _ZGVdN4v_sin_sse_wrapper
 #include "../svml_d_sin4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core.c
similarity index 60%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core.c
index f4482d3..44ff161 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sin4_core.c
@@ -1,5 +1,5 @@
 /* Multiple versions of vectorized sin, vector length is 4.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+   Copyright (C) 2017 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
@@ -16,21 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN4v_sin
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVdN4v_sin)
-        .type   _ZGVdN4v_sin, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN4v_sin_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN4v_sin_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN4v_sin)
-libmvec_hidden_def (_ZGVdN4v_sin)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVdN4v_sin _ZGVdN4v_sin_sse_wrapper
-#include "../svml_d_sin4_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN4v_sin, __GI__ZGVdN4v_sin, __redirect__ZGVdN4v_sin)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core-avx2.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core-avx2.S
index 2b15889..89cabc3 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized sin.
+/* AVX2 version of vectorized sin.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -19,19 +19,5 @@
 #include <sysdep.h>
 #include <init-arch.h>
 
-	.text
-ENTRY (_ZGVeN8v_sin)
-        .type   _ZGVeN8v_sin, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVeN8v_sin_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN8v_sin_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN8v_sin_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN8v_sin)
-
 #define _ZGVeN8v_sin _ZGVeN8v_sin_avx2_wrapper
 #include "../svml_d_sin8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core.c
index 5a17e11..0391268 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sin, vector length is 8.
+   Copyright (C) 2017 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
@@ -16,21 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN8v_sin
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN8v_sin, __GI__ZGVeN8v_sin, __redirect__ZGVeN8v_sin)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos2_core-sse2.S
similarity index 66%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_sincos2_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_sincos2_core-sse2.S
index 13279e3..7c15800 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos2_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized sincos.
+/* SSE2 version of vectorized sincos.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN2vvv_sincos)
-        .type   _ZGVbN2vvv_sincos, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2vvv_sincos_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2vvv_sincos_sse2(%rip), %rax
-        ret
-END (_ZGVbN2vvv_sincos)
-libmvec_hidden_def (_ZGVbN2vvv_sincos)
-
 #define _ZGVbN2vvv_sincos _ZGVbN2vvv_sincos_sse2
 #include "../svml_d_sincos2_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos2_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_sincos2_core.c
index 5a17e11..5902894 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos2_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sincos, vector length is 2.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN2vvv_sincos
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN2vvv_sincos, __GI__ZGVbN2vvv_sincos,
+	       __redirect__ZGVbN2vvv_sincos)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos4_core-sse.S
similarity index 66%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_sincos4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_d_sincos4_core-sse.S
index 8aacb8e..739efc3 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos4_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized sincos.
+/* SSE version of vectorized sincos.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN4vvv_sincos)
-        .type   _ZGVdN4vvv_sincos, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN4vvv_sincos_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN4vvv_sincos_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN4vvv_sincos)
-libmvec_hidden_def (_ZGVdN4vvv_sincos)
-
 #define _ZGVdN4vvv_sincos _ZGVdN4vvv_sincos_sse_wrapper
 #include "../svml_d_sincos4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos4_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_sincos4_core.c
index 5a17e11..d55aa6f 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos4_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sincos, vector length is 4.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN4vvv_sincos
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN4vvv_sincos, __GI__ZGVdN4vvv_sincos,
+	       __redirect__ZGVdN4vvv_sincos)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core-avx2.S
similarity index 62%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core-avx2.S
index 5a17e11..026d93c 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized exp.
+/* AVX2 version of vectorized sincos.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
-
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#define _ZGVeN8vvv_sincos _ZGVeN8vvv_sincos_avx2_wrapper
+#include "../svml_d_sincos8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core.S
deleted file mode 100644
index 3c0abc3..0000000
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Multiple versions of vectorized sincos.
-   Copyright (C) 2014-2017 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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVeN8vvv_sincos)
-        .type   _ZGVeN8vvv_sincos, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVeN8vvv_sincos_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN8vvv_sincos_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN8vvv_sincos_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN8vvv_sincos)
-
-#define _ZGVeN8vvv_sincos _ZGVeN8vvv_sincos_avx2_wrapper
-#include "../svml_d_sincos8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core.c
index 5a17e11..f78146f 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sincos, vector length is 8.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN8vvv_sincos
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN8vvv_sincos, __GI__ZGVeN8vvv_sincos,
+	       __redirect__ZGVeN8vvv_sincos)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core-avx2.S
similarity index 64%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core-avx2.S
index cd67665..f9c0023 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized cosf.
+/* AVX2 version of vectorized cosf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,22 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVeN16v_cosf)
-        .type   _ZGVeN16v_cosf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVeN16v_cosf_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN16v_cosf_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN16v_cosf_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN16v_cosf)
-
 #define _ZGVeN16v_cosf _ZGVeN16v_cosf_avx2_wrapper
 #include "../svml_s_cosf16_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core.c
index 5a17e11..186c012 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized cosf, vector length is 16.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN16v_cosf
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN16v_cosf, __GI__ZGVeN16v_cosf,
+	       __redirect__ZGVeN16v_cosf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core-sse2.S
similarity index 66%
copy from sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core-sse2.S
index d73d7c7..6a4ba6a 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized cosf, vector length is 4.
+/* SSE2 version of vectorized cosf, vector length is 4.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN4v_cosf)
-        .type   _ZGVbN4v_cosf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN4v_cosf_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN4v_cosf_sse2(%rip), %rax
-        ret
-END (_ZGVbN4v_cosf)
-libmvec_hidden_def (_ZGVbN4v_cosf)
-
 #define _ZGVbN4v_cosf _ZGVbN4v_cosf_sse2
 #include "../svml_s_cosf4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core.c
similarity index 61%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core.c
index d73d7c7..8eb5e03 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf4_core.c
@@ -1,5 +1,5 @@
 /* Multiple versions of vectorized cosf, vector length is 4.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN4v_cosf
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN4v_cosf)
-        .type   _ZGVbN4v_cosf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN4v_cosf_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN4v_cosf_sse2(%rip), %rax
-        ret
-END (_ZGVbN4v_cosf)
-libmvec_hidden_def (_ZGVbN4v_cosf)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN4v_cosf _ZGVbN4v_cosf_sse2
-#include "../svml_s_cosf4_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN4v_cosf, __GI__ZGVbN4v_cosf,
+	       __redirect__ZGVbN4v_cosf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf8_core-sse.S
similarity index 66%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_cosf8_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_cosf8_core-sse.S
index f7530c1..3a4741b 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf8_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized cosf, vector length is 8.
+/* SSE version of vectorized cosf, vector length is 8.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN8v_cosf)
-        .type   _ZGVdN8v_cosf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN8v_cosf_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN8v_cosf_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN8v_cosf)
-libmvec_hidden_def (_ZGVdN8v_cosf)
-
 #define _ZGVdN8v_cosf _ZGVdN8v_cosf_sse_wrapper
 #include "../svml_s_cosf8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf8_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_cosf8_core.c
index 5a17e11..13d2e9d 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf8_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized cosf, vector length is 8.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN8v_cosf
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN8v_cosf, __GI__ZGVdN8v_cosf,
+	       __redirect__ZGVdN8v_cosf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core-avx2.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core-avx2.S
index 3998f61..9ff196e 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized expf.
+/* AVX2 version of vectorized expf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -19,19 +19,5 @@
 #include <sysdep.h>
 #include <init-arch.h>
 
-	.text
-ENTRY (_ZGVeN16v_expf)
-        .type   _ZGVeN16v_expf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVeN16v_expf_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN16v_expf_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN16v_expf_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN16v_expf)
-
 #define _ZGVeN16v_expf _ZGVeN16v_expf_avx2_wrapper
 #include "../svml_s_expf16_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core.c
index 5a17e11..42566ac 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized expf, vector length is 16.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN16v_expf
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN16v_expf, __GI__ZGVeN16v_expf,
+	       __redirect__ZGVeN16v_expf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_expf4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_expf4_core-sse2.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_expf4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_expf4_core-sse2.S
index 8051720..393e420 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_expf4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_expf4_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized expf.
+/* SSE2 version of vectorized expf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN4v_expf)
-        .type   _ZGVbN4v_expf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN4v_expf_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN4v_expf_sse2(%rip), %rax
-        ret
-END (_ZGVbN4v_expf)
-libmvec_hidden_def (_ZGVbN4v_expf)
-
 #define _ZGVbN4v_expf _ZGVbN4v_expf_sse2
 #include "../svml_s_expf4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_expf4_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_expf4_core.c
index 5a17e11..5218e3d 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_expf4_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized expf, vector length is 4.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN4v_expf
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN4v_expf, __GI__ZGVbN4v_expf,
+	       __redirect__ZGVbN4v_expf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_expf8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_expf8_core-sse.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_expf8_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_expf8_core-sse.S
index 6ffb1fd..a75b601 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_expf8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_expf8_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized expf.
+/* SSE version of vectorized expf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN8v_expf)
-        .type   _ZGVdN8v_expf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN8v_expf_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN8v_expf_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN8v_expf)
-libmvec_hidden_def (_ZGVdN8v_expf)
-
 #define _ZGVdN8v_expf _ZGVdN8v_expf_sse_wrapper
 #include "../svml_s_expf8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_expf8_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_expf8_core.c
index 5a17e11..6badac4 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_expf8_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized expf, vector length is 8.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN8v_expf
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN8v_expf, __GI__ZGVdN8v_expf,
+	       __redirect__ZGVdN8v_expf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core-avx2.S
similarity index 64%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core-avx2.S
index 8ab0319..2a87049 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized logf.
+/* AVX2 version of vectorized logf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,22 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVeN16v_logf)
-        .type   _ZGVeN16v_logf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVeN16v_logf_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN16v_logf_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN16v_logf_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN16v_logf)
-
 #define _ZGVeN16v_logf _ZGVeN16v_logf_avx2_wrapper
 #include "../svml_s_logf16_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core.c
index 5a17e11..81c5653 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized logf, vector length is 16.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN16v_logf
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN16v_logf, __GI__ZGVeN16v_logf,
+	       __redirect__ZGVeN16v_logf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_logf4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_logf4_core-sse2.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_logf4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_logf4_core-sse2.S
index 4e0e36d..f6ef828 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_logf4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_logf4_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized logf.
+/* SSE2 version of vectorized logf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN4v_logf)
-        .type   _ZGVbN4v_logf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN4v_logf_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN4v_logf_sse2(%rip), %rax
-        ret
-END (_ZGVbN4v_logf)
-libmvec_hidden_def (_ZGVbN4v_logf)
-
 #define _ZGVbN4v_logf _ZGVbN4v_logf_sse2
 #include "../svml_s_logf4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_logf4_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_logf4_core.c
index 5a17e11..a32855e 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_logf4_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized logf, vector length is 4.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN4v_logf
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN4v_logf, __GI__ZGVbN4v_logf,
+	       __redirect__ZGVbN4v_logf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_logf8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_logf8_core-sse.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_logf8_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_logf8_core-sse.S
index f4b82de..e5a46ef 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_logf8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_logf8_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized logf.
+/* SSE version of vectorized logf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN8v_logf)
-        .type   _ZGVdN8v_logf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN8v_logf_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN8v_logf_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN8v_logf)
-libmvec_hidden_def (_ZGVdN8v_logf)
-
 #define _ZGVdN8v_logf _ZGVdN8v_logf_sse_wrapper
 #include "../svml_s_logf8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_logf8_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_logf8_core.c
index 5a17e11..b4efa7a 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_logf8_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized logf, vector length is 8.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN8v_logf
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN8v_logf, __GI__ZGVdN8v_logf,
+	       __redirect__ZGVdN8v_logf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core-avx2.S
similarity index 62%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core-avx2.S
index 5a17e11..ec6ec70 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized exp.
+/* AVX2 version of vectorized powf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
-
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#define _ZGVeN16vv_powf _ZGVeN16vv_powf_avx2_wrapper
+#include "../svml_s_powf16_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core.S
deleted file mode 100644
index 6d10c75..0000000
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Multiple versions of vectorized powf.
-   Copyright (C) 2014-2017 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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVeN16vv_powf)
-        .type   _ZGVeN16vv_powf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVeN16vv_powf_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN16vv_powf_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN16vv_powf_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN16vv_powf)
-
-#define _ZGVeN16vv_powf _ZGVeN16vv_powf_avx2_wrapper
-#include "../svml_s_powf16_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core.c
index 5a17e11..25c706a 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized powf, vector length is 16.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN16vv_powf
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN16vv_powf, __GI__ZGVeN16vv_powf,
+	       __redirect__ZGVeN16vv_powf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_powf4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_powf4_core-sse2.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_powf4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_powf4_core-sse2.S
index 785b549..30b77b6 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_powf4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_powf4_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized powf.
+/* SSE2 version of vectorized powf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN4vv_powf)
-        .type   _ZGVbN4vv_powf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN4vv_powf_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN4vv_powf_sse2(%rip), %rax
-        ret
-END (_ZGVbN4vv_powf)
-libmvec_hidden_def (_ZGVbN4vv_powf)
-
 #define _ZGVbN4vv_powf _ZGVbN4vv_powf_sse2
 #include "../svml_s_powf4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_powf4_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_powf4_core.c
index 5a17e11..4d9821c 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_powf4_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized powf, vector length is 4.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN4vv_powf
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN4vv_powf, __GI__ZGVbN4vv_powf,
+	       __redirect__ZGVbN4vv_powf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_powf8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_powf8_core-sse.S
similarity index 66%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_powf8_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_powf8_core-sse.S
index 1f6a073..824042d 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_powf8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_powf8_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized powf.
+/* SSE version of vectorized powf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN8vv_powf)
-        .type   _ZGVdN8vv_powf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN8vv_powf_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN8vv_powf_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN8vv_powf)
-libmvec_hidden_def (_ZGVdN8vv_powf)
-
 #define _ZGVdN8vv_powf _ZGVdN8vv_powf_sse_wrapper
 #include "../svml_s_powf8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_powf8_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_powf8_core.c
index 5a17e11..64ac764 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_powf8_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sinf, vector length is 8.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN8vv_powf
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN8vv_powf, __GI__ZGVdN8vv_powf,
+	       __redirect__ZGVdN8vv_powf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core-avx2.S
similarity index 62%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core-avx2.S
index 5a17e11..a145d2f 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized exp.
+/* AVX2 version of vectorized sincosf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
-
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#define _ZGVeN16vvv_sincosf _ZGVeN16vvv_sincosf_avx2_wrapper
+#include "../svml_s_sincosf16_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core.S
deleted file mode 100644
index 0545460..0000000
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Multiple versions of vectorized sincosf.
-   Copyright (C) 2014-2017 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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVeN16vvv_sincosf)
-        .type   _ZGVeN16vvv_sincosf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVeN16vvv_sincosf_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN16vvv_sincosf_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN16vvv_sincosf_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN16vvv_sincosf)
-
-#define _ZGVeN16vvv_sincosf _ZGVeN16vvv_sincosf_avx2_wrapper
-#include "../svml_s_sincosf16_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core.c
index 5a17e11..ac66a4e 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sincosf, vector length is 16.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN16vvv_sincosf
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN16vvv_sincosf, __GI__ZGVeN16vvv_sincosf,
+	       __redirect__ZGVeN16vvv_sincosf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf4_core-sse2.S
similarity index 66%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_sincosf4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_sincosf4_core-sse2.S
index a249be3..dc25091 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf4_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized sincosf.
+/* SSE2 version of vectorized sincosf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN4vvv_sincosf)
-        .type   _ZGVbN4vvv_sincosf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN4vvv_sincosf_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN4vvv_sincosf_sse2(%rip), %rax
-        ret
-END (_ZGVbN4vvv_sincosf)
-libmvec_hidden_def (_ZGVbN4vvv_sincosf)
-
 #define _ZGVbN4vvv_sincosf _ZGVbN4vvv_sincosf_sse2
 #include "../svml_s_sincosf4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf4_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_sincosf4_core.c
index 5a17e11..fc81d43 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf4_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sincosf, vector length is 4.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN4vvv_sincosf
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN4vvv_sincosf, __GI__ZGVbN4vvv_sincosf,
+	       __redirect__ZGVbN4vvv_sincosf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf8_core-sse.S
similarity index 65%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_sincosf8_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_sincosf8_core-sse.S
index 320fd86..2541297 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf8_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized sincosf.
+/* SSE version of vectorized sincosf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN8vvv_sincosf)
-        .type   _ZGVdN8vvv_sincosf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVdN8vvv_sincosf_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN8vvv_sincosf_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN8vvv_sincosf)
-libmvec_hidden_def (_ZGVdN8vvv_sincosf)
-
 #define _ZGVdN8vvv_sincosf _ZGVdN8vvv_sincosf_sse_wrapper
 #include "../svml_s_sincosf8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf8_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_sincosf8_core.c
index 5a17e11..cd57ff3 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf8_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sincosf, vector length is 8.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN8vvv_sincosf
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN8vvv_sincosf, __GI__ZGVdN8vvv_sincosf,
+	       __redirect__ZGVdN8vvv_sincosf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core-avx2.S
similarity index 64%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core-avx2.S
index 2c18dbc..f7d0c3f 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core-avx2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized sinf.
+/* AVX2 version of vectorized sinf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,22 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVeN16v_sinf)
-        .type   _ZGVeN16v_sinf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVeN16v_sinf_skx(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512DQ_Usable)
-        jnz     2f
-        leaq    _ZGVeN16v_sinf_knl(%rip), %rax
-	HAS_ARCH_FEATURE (AVX512F_Usable)
-        jnz     2f
-        leaq    _ZGVeN16v_sinf_avx2_wrapper(%rip), %rax
-2:      ret
-END (_ZGVeN16v_sinf)
-
 #define _ZGVeN16v_sinf _ZGVeN16v_sinf_avx2_wrapper
 #include "../svml_s_sinf16_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core.c
index 5a17e11..d2e15f0 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sinf, vector length is 16.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVeN16v_sinf
+#include "ifunc-mathvec-avx512.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVeN16v_sinf, __GI__ZGVeN16v_sinf,
+	       __redirect__ZGVeN16v_sinf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf4_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf4_core-sse2.S
similarity index 67%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_sinf4_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_sinf4_core-sse2.S
index 3556473..a9de674 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf4_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf4_core-sse2.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized sinf.
+/* SSE2 version of vectorized sinf.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVbN4v_sinf)
-        .type   _ZGVbN4v_sinf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN4v_sinf_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN4v_sinf_sse2(%rip), %rax
-        ret
-END (_ZGVbN4v_sinf)
-libmvec_hidden_def (_ZGVbN4v_sinf)
-
 #define _ZGVbN4v_sinf _ZGVbN4v_sinf_sse2
 #include "../svml_s_sinf4_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf4_core.c
similarity index 57%
copy from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
copy to sysdeps/x86_64/fpu/multiarch/svml_s_sinf4_core.c
index 5a17e11..466b798 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf4_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sinf, vector length is 4.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVbN4v_sinf
+#include "ifunc-mathvec-sse4_1.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN4v_sinf, __GI__ZGVbN4v_sinf,
+	       __redirect__ZGVbN4v_sinf)
+  __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf8_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf8_core-sse.S
similarity index 66%
rename from sysdeps/x86_64/fpu/multiarch/svml_s_sinf8_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_sinf8_core-sse.S
index 674e88b..fbf6bd2 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf8_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf8_core-sse.S
@@ -1,4 +1,4 @@
-/* Multiple versions of vectorized sinf, vector length is 8.
+/* SSE version of vectorized sinf, vector length is 8.
    Copyright (C) 2014-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY (_ZGVdN8v_sinf)
-        .type   _ZGVdN8v_sinf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-1:      leaq    _ZGVdN8v_sinf_avx2(%rip), %rax
-	HAS_ARCH_FEATURE (AVX2_Usable)
-        jz      2f
-        ret
-2:      leaq    _ZGVdN8v_sinf_sse_wrapper(%rip), %rax
-        ret
-END (_ZGVdN8v_sinf)
-libmvec_hidden_def (_ZGVdN8v_sinf)
-
 #define _ZGVdN8v_sinf _ZGVdN8v_sinf_sse_wrapper
 #include "../svml_s_sinf8_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf8_core.c
similarity index 57%
rename from sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
rename to sysdeps/x86_64/fpu/multiarch/svml_s_sinf8_core.c
index 5a17e11..cb5c992 100644
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core.S
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf8_core.c
@@ -1,5 +1,5 @@
-/* Multiple versions of vectorized exp.
-   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+/* Multiple versions of vectorized sinf, vector length is 8.
+   Copyright (C) 2017 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
@@ -16,21 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
+#define SYMBOL_NAME _ZGVdN8v_sinf
+#include "ifunc-mathvec-avx2.h"
 
-	.text
-ENTRY (_ZGVbN2v_exp)
-        .type   _ZGVbN2v_exp, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-        leaq    _ZGVbN2v_exp_sse4(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-        jz      2f
-        ret
-2:      leaq    _ZGVbN2v_exp_sse2(%rip), %rax
-        ret
-END (_ZGVbN2v_exp)
-libmvec_hidden_def (_ZGVbN2v_exp)
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
 
-#define _ZGVbN2v_exp _ZGVbN2v_exp_sse2
-#include "../svml_d_exp2_core.S"
+#ifdef SHARED
+__hidden_ver1 (_ZGVdN8v_sinf, __GI__ZGVdN8v_sinf,
+	       __redirect__ZGVdN8v_sinf)
+  __attribute__ ((visibility ("hidden")));
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c0fe5c7a0a3e0d94b380dc94fe0cc6f59e55c0bd

commit c0fe5c7a0a3e0d94b380dc94fe0cc6f59e55c0bd
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Jul 18 13:56:17 2017 -0700

    x86-64: Convert libm IFUNC selectors to C

diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile
index 3454215..86ddde3 100644
--- a/sysdeps/x86_64/fpu/multiarch/Makefile
+++ b/sysdeps/x86_64/fpu/multiarch/Makefile
@@ -2,6 +2,10 @@ ifeq ($(subdir),math)
 libm-sysdep_routines += s_floor-c s_ceil-c s_floorf-c s_ceilf-c \
 			s_rint-c s_rintf-c s_nearbyint-c s_nearbyintf-c
 
+libm-sysdep_routines += s_ceil-sse4_1 s_ceilf-sse4_1 s_floor-sse4_1 \
+			s_floorf-sse4_1 s_nearbyint-sse4_1 \
+			s_nearbyintf-sse4_1 s_rint-sse4_1 s_rintf-sse4_1
+
 libm-sysdep_routines += e_exp-fma4 e_log-fma4 e_pow-fma4 s_atan-fma4 \
 			e_asin-fma4 e_atan2-fma4 s_sin-fma4 s_tan-fma4 \
 			mplog-fma4 mpa-fma4 slowexp-fma4 slowpow-fma4 \
diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf.S b/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1.h
similarity index 62%
copy from sysdeps/x86_64/fpu/multiarch/s_floorf.S
copy to sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1.h
index 8613f73..ad8d878 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_floorf.S
+++ b/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1.h
@@ -1,6 +1,6 @@
-/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+/* Common definition for ifunc selections optimized with SSE4.1.
+   Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@gmail.come>, 2011.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,23 +16,18 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
 #include <init-arch.h>
 
+extern __typeof (REDIRECT_NAME) OPTIMIZE (c) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse41) attribute_hidden;
 
-ENTRY(__floorf)
-	.type	__floorf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__floorf_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__floorf_c(%rip), %rax
-2:	ret
-END(__floorf)
-weak_alias (__floorf, floorf)
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  const struct cpu_features* cpu_features = __get_cpu_features ();
 
+  if (CPU_FEATURES_CPU_P (cpu_features, SSE4_1))
+    return OPTIMIZE (sse41);
 
-ENTRY(__floorf_sse41)
-	roundss	$9, %xmm0, %xmm0
-	ret
-END(__floorf_sse41)
+  return OPTIMIZE (c);
+}
diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil.S b/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S
similarity index 77%
copy from sysdeps/x86_64/fpu/multiarch/s_ceil.S
copy to sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S
index f8eef43..6d6be97 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_ceil.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S
@@ -16,22 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
-
-
-ENTRY(__ceil)
-	.type	__ceil, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__ceil_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__ceil_c(%rip), %rax
-2:	ret
-END(__ceil)
-weak_alias (__ceil, ceil)
-
+#include <sysdep.h>
 
+	.section .text.sse4.1,"ax",@progbits
 ENTRY(__ceil_sse41)
 	roundsd	$10, %xmm0, %xmm0
 	ret
diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil.S b/sysdeps/x86_64/fpu/multiarch/s_ceil.c
similarity index 63%
rename from sysdeps/x86_64/fpu/multiarch/s_ceil.S
rename to sysdeps/x86_64/fpu/multiarch/s_ceil.c
index f8eef43..2c01957 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_ceil.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_ceil.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+/* Multiple versions of __ceil.
+   Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@gmail.come>, 2011.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,23 +16,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
+#define ceil __redirect_ceil
+#define __ceil __redirect___ceil
+#include <math.h>
+#undef ceil
+#undef __ceil
 
+#define SYMBOL_NAME ceil
+#include "ifunc-sse4_1.h"
 
-ENTRY(__ceil)
-	.type	__ceil, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__ceil_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__ceil_c(%rip), %rax
-2:	ret
-END(__ceil)
+libc_ifunc_redirected (__redirect_ceil, __ceil, IFUNC_SELECTOR ());
 weak_alias (__ceil, ceil)
-
-
-ENTRY(__ceil_sse41)
-	roundsd	$10, %xmm0, %xmm0
-	ret
-END(__ceil_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceilf.S b/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S
similarity index 77%
copy from sysdeps/x86_64/fpu/multiarch/s_ceilf.S
copy to sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S
index 076f10f..9081ce6 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_ceilf.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S
@@ -16,22 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
-
-
-ENTRY(__ceilf)
-	.type	__ceilf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__ceilf_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__ceilf_c(%rip), %rax
-2:	ret
-END(__ceilf)
-weak_alias (__ceilf, ceilf)
-
+#include <sysdep.h>
 
+	.section .text.sse4.1,"ax",@progbits
 ENTRY(__ceilf_sse41)
 	roundss	$10, %xmm0, %xmm0
 	ret
diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceilf.S b/sysdeps/x86_64/fpu/multiarch/s_ceilf.c
similarity index 63%
rename from sysdeps/x86_64/fpu/multiarch/s_ceilf.S
rename to sysdeps/x86_64/fpu/multiarch/s_ceilf.c
index 076f10f..090de04 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_ceilf.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_ceilf.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+/* Multiple versions of __ceilf.
+   Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@gmail.come>, 2011.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,23 +16,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
+#define ceilf __redirect_ceilf
+#define __ceilf __redirect___ceilf
+#include <math.h>
+#undef ceilf
+#undef __ceilf
 
+#define SYMBOL_NAME ceilf
+#include "ifunc-sse4_1.h"
 
-ENTRY(__ceilf)
-	.type	__ceilf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__ceilf_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__ceilf_c(%rip), %rax
-2:	ret
-END(__ceilf)
+libc_ifunc_redirected (__redirect_ceilf, __ceilf, IFUNC_SELECTOR ());
 weak_alias (__ceilf, ceilf)
-
-
-ENTRY(__ceilf_sse41)
-	roundss	$10, %xmm0, %xmm0
-	ret
-END(__ceilf_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor.S b/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S
similarity index 77%
copy from sysdeps/x86_64/fpu/multiarch/s_floor.S
copy to sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S
index f519ab2..022a4ac 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_floor.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S
@@ -16,22 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
-
-
-ENTRY(__floor)
-	.type	__floor, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__floor_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__floor_c(%rip), %rax
-2:	ret
-END(__floor)
-weak_alias (__floor, floor)
-
+#include <sysdep.h>
 
+	.section .text.sse4.1,"ax",@progbits
 ENTRY(__floor_sse41)
 	roundsd	$9, %xmm0, %xmm0
 	ret
diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor.S b/sysdeps/x86_64/fpu/multiarch/s_floor.c
similarity index 63%
rename from sysdeps/x86_64/fpu/multiarch/s_floor.S
rename to sysdeps/x86_64/fpu/multiarch/s_floor.c
index f519ab2..3dd0f81 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_floor.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_floor.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+/* Multiple versions of __floor.
+   Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@gmail.come>, 2011.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,23 +16,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
+#define floor __redirect_floor
+#define __floor __redirect___floor
+#include <math.h>
+#undef floor
+#undef __floor
 
+#define SYMBOL_NAME floor
+#include "ifunc-sse4_1.h"
 
-ENTRY(__floor)
-	.type	__floor, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__floor_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__floor_c(%rip), %rax
-2:	ret
-END(__floor)
+libc_ifunc_redirected (__redirect_floor, __floor, IFUNC_SELECTOR ());
 weak_alias (__floor, floor)
-
-
-ENTRY(__floor_sse41)
-	roundsd	$9, %xmm0, %xmm0
-	ret
-END(__floor_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf.S b/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S
similarity index 76%
copy from sysdeps/x86_64/fpu/multiarch/s_floorf.S
copy to sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S
index 8613f73..ea63144 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_floorf.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S
@@ -16,22 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
-
-
-ENTRY(__floorf)
-	.type	__floorf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__floorf_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__floorf_c(%rip), %rax
-2:	ret
-END(__floorf)
-weak_alias (__floorf, floorf)
-
+#include <sysdep.h>
 
+	.section .text.sse4.1,"ax",@progbits
 ENTRY(__floorf_sse41)
 	roundss	$9, %xmm0, %xmm0
 	ret
diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf.S b/sysdeps/x86_64/fpu/multiarch/s_floorf.c
similarity index 63%
rename from sysdeps/x86_64/fpu/multiarch/s_floorf.S
rename to sysdeps/x86_64/fpu/multiarch/s_floorf.c
index 8613f73..d6cf14d 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_floorf.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_floorf.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+/* Multiple versions of __floorf.
+   Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@gmail.come>, 2011.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,23 +16,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
+#define floorf __redirect_floorf
+#define __floorf __redirect___floorf
+#include <math.h>
+#undef floorf
+#undef __floorf
 
+#define SYMBOL_NAME floorf
+#include "ifunc-sse4_1.h"
 
-ENTRY(__floorf)
-	.type	__floorf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__floorf_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__floorf_c(%rip), %rax
-2:	ret
-END(__floorf)
+libc_ifunc_redirected (__redirect_floorf, __floorf, IFUNC_SELECTOR ());
 weak_alias (__floorf, floorf)
-
-
-ENTRY(__floorf_sse41)
-	roundss	$9, %xmm0, %xmm0
-	ret
-END(__floorf_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S
similarity index 75%
copy from sysdeps/x86_64/fpu/multiarch/s_nearbyint.S
copy to sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S
index 5a734f6..68934aa 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S
@@ -16,22 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
-
-
-ENTRY(__nearbyint)
-	.type	__nearbyint, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__nearbyint_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__nearbyint_c(%rip), %rax
-2:	ret
-END(__nearbyint)
-weak_alias (__nearbyint, nearbyint)
-
+#include <sysdep.h>
 
+	.section .text.sse4.1,"ax",@progbits
 ENTRY(__nearbyint_sse41)
 	roundsd	$0xc, %xmm0, %xmm0
 	ret
diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c
similarity index 62%
rename from sysdeps/x86_64/fpu/multiarch/s_nearbyint.S
rename to sysdeps/x86_64/fpu/multiarch/s_nearbyint.c
index 5a734f6..05579c6 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+/* Multiple versions of __nearbyint.
+   Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@gmail.come>, 2011.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,23 +16,15 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
+#define nearbyint __redirect_nearbyint
+#define __nearbyint __redirect___nearbyint
+#include <math.h>
+#undef nearbyint
+#undef __nearbyint
 
+#define SYMBOL_NAME nearbyint
+#include "ifunc-sse4_1.h"
 
-ENTRY(__nearbyint)
-	.type	__nearbyint, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__nearbyint_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__nearbyint_c(%rip), %rax
-2:	ret
-END(__nearbyint)
+libc_ifunc_redirected (__redirect_nearbyint, __nearbyint,
+		       IFUNC_SELECTOR ());
 weak_alias (__nearbyint, nearbyint)
-
-
-ENTRY(__nearbyint_sse41)
-	roundsd	$0xc, %xmm0, %xmm0
-	ret
-END(__nearbyint_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S
similarity index 75%
copy from sysdeps/x86_64/fpu/multiarch/s_nearbyintf.S
copy to sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S
index ad79fd6..16bd905 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S
@@ -16,22 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
-
-
-ENTRY(__nearbyintf)
-	.type	__nearbyintf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__nearbyintf_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__nearbyintf_c(%rip), %rax
-2:	ret
-END(__nearbyintf)
-weak_alias (__nearbyintf, nearbyintf)
-
+#include <sysdep.h>
 
+	.section .text.sse4.1,"ax",@progbits
 ENTRY(__nearbyintf_sse41)
 	roundss	$0xc, %xmm0, %xmm0
 	ret
diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c
similarity index 62%
rename from sysdeps/x86_64/fpu/multiarch/s_nearbyintf.S
rename to sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c
index ad79fd6..e716c94 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+/* Multiple versions of __nearbyintf.
+   Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@gmail.come>, 2011.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,23 +16,15 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
+#define nearbyintf __redirect_nearbyintf
+#define __nearbyintf __redirect___nearbyintf
+#include <math.h>
+#undef nearbyintf
+#undef __nearbyintf
 
+#define SYMBOL_NAME nearbyintf
+#include "ifunc-sse4_1.h"
 
-ENTRY(__nearbyintf)
-	.type	__nearbyintf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__nearbyintf_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__nearbyintf_c(%rip), %rax
-2:	ret
-END(__nearbyintf)
+libc_ifunc_redirected (__redirect_nearbyintf, __nearbyintf,
+		       IFUNC_SELECTOR ());
 weak_alias (__nearbyintf, nearbyintf)
-
-
-ENTRY(__nearbyintf_sse41)
-	roundss	$0xc, %xmm0, %xmm0
-	ret
-END(__nearbyintf_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint.S b/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S
similarity index 77%
copy from sysdeps/x86_64/fpu/multiarch/s_rint.S
copy to sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S
index 4f628a9..9224aa9 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_rint.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S
@@ -16,22 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
-
-
-ENTRY(__rint)
-	.type	__rint, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__rint_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__rint_c(%rip), %rax
-2:	ret
-END(__rint)
-weak_alias (__rint, rint)
-
+#include <sysdep.h>
 
+	.section .text.sse4.1,"ax",@progbits
 ENTRY(__rint_sse41)
 	roundsd	$4, %xmm0, %xmm0
 	ret
diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint.S b/sysdeps/x86_64/fpu/multiarch/s_rint.c
similarity index 64%
rename from sysdeps/x86_64/fpu/multiarch/s_rint.S
rename to sysdeps/x86_64/fpu/multiarch/s_rint.c
index 4f628a9..ad44e7c 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_rint.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_rint.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+/* Multiple versions of __rint.
+   Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@gmail.come>, 2011.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,23 +16,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
+#define rint __redirect_rint
+#define __rint __redirect___rint
+#include <math.h>
+#undef rint
+#undef __rint
 
+#define SYMBOL_NAME rint
+#include "ifunc-sse4_1.h"
 
-ENTRY(__rint)
-	.type	__rint, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__rint_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__rint_c(%rip), %rax
-2:	ret
-END(__rint)
+libc_ifunc_redirected (__redirect_rint, __rint, IFUNC_SELECTOR ());
 weak_alias (__rint, rint)
-
-
-ENTRY(__rint_sse41)
-	roundsd	$4, %xmm0, %xmm0
-	ret
-END(__rint_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_rintf.S b/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S
similarity index 77%
copy from sysdeps/x86_64/fpu/multiarch/s_rintf.S
copy to sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S
index dee4ad7..7f47592 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_rintf.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S
@@ -16,22 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
-
-
-ENTRY(__rintf)
-	.type	__rintf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__rintf_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__rintf_c(%rip), %rax
-2:	ret
-END(__rintf)
-weak_alias (__rintf, rintf)
-
+#include <sysdep.h>
 
+	.section .text.sse4.1,"ax",@progbits
 ENTRY(__rintf_sse41)
 	roundss	$4, %xmm0, %xmm0
 	ret
diff --git a/sysdeps/x86_64/fpu/multiarch/s_rintf.S b/sysdeps/x86_64/fpu/multiarch/s_rintf.c
similarity index 63%
rename from sysdeps/x86_64/fpu/multiarch/s_rintf.S
rename to sysdeps/x86_64/fpu/multiarch/s_rintf.c
index dee4ad7..88f3052 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_rintf.S
+++ b/sysdeps/x86_64/fpu/multiarch/s_rintf.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+/* Multiple versions of __rintf.
+   Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@gmail.come>, 2011.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,23 +16,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
-#include <init-arch.h>
+#define rintf __redirect_rintf
+#define __rintf __redirect___rintf
+#include <math.h>
+#undef rintf
+#undef __rintf
 
+#define SYMBOL_NAME rintf
+#include "ifunc-sse4_1.h"
 
-ENTRY(__rintf)
-	.type	__rintf, @gnu_indirect_function
-	LOAD_RTLD_GLOBAL_RO_RDX
-	leaq	__rintf_sse41(%rip), %rax
-	HAS_CPU_FEATURE (SSE4_1)
-	jnz	2f
-	leaq	__rintf_c(%rip), %rax
-2:	ret
-END(__rintf)
+libc_ifunc_redirected (__redirect_rintf, __rintf, IFUNC_SELECTOR ());
 weak_alias (__rintf, rintf)
-
-
-ENTRY(__rintf_sse41)
-	roundss	$4, %xmm0, %xmm0
-	ret
-END(__rintf_sse41)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b7ef1ce037602a55c47cfe1493d954794ed0ad61

commit b7ef1ce037602a55c47cfe1493d954794ed0ad61
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jul 19 08:46:08 2017 -0700

    i386: Don't define multiarch __memmove_chk in libc.a [BZ #21791]
    
    There is no need to define multiarch __memmove_chk in libc.a.
    
    	[BZ #21791]
    	* sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S
    	(MEMCPY_CHK): Define only if SHARED is defined.
    	* sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S (MEMCPY_CHK):
    	Likewise.
    	* sysdeps/i386/i686/multiarch/memcpy-ssse3.S (MEMCPY_CHK):
    	Likewise.

diff --git a/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S b/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S
index 2fe2072..fd3f499 100644
--- a/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S
+++ b/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S
@@ -56,7 +56,7 @@
 # define RETURN	RETURN_END; CFI_PUSH (%ebx)
 
 	.section .text.sse2,"ax",@progbits
-# if !defined USE_AS_BCOPY
+# if !defined USE_AS_BCOPY && defined SHARED
 ENTRY (MEMCPY_CHK)
 	movl	12(%esp), %eax
 	cmpl	%eax, 16(%esp)
diff --git a/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S b/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S
index 687e083..46d6597 100644
--- a/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S
+++ b/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S
@@ -100,7 +100,7 @@
 #endif
 
 	.section .text.ssse3,"ax",@progbits
-#if !defined USE_AS_BCOPY
+#if !defined USE_AS_BCOPY && defined SHARED
 ENTRY (MEMCPY_CHK)
 	movl	12(%esp), %eax
 	cmpl	%eax, 16(%esp)
diff --git a/sysdeps/i386/i686/multiarch/memcpy-ssse3.S b/sysdeps/i386/i686/multiarch/memcpy-ssse3.S
index 53e8a6c..8b33153 100644
--- a/sysdeps/i386/i686/multiarch/memcpy-ssse3.S
+++ b/sysdeps/i386/i686/multiarch/memcpy-ssse3.S
@@ -89,7 +89,7 @@
 # endif
 
 	.section .text.ssse3,"ax",@progbits
-# if !defined USE_AS_BCOPY
+# if !defined USE_AS_BCOPY && defined SHARED
 ENTRY (MEMCPY_CHK)
 	movl	12(%esp), %eax
 	cmpl	%eax, 16(%esp)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=09ffe2436cc6f9c3814753d4a70496e894e7a5bc

commit 09ffe2436cc6f9c3814753d4a70496e894e7a5bc
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jul 19 10:56:19 2017 -0700

    Avoid accessing corrupted stack from __stack_chk_fail [BZ #21752]
    
    __libc_argv[0] points to address on stack and __libc_secure_getenv
    accesses environment variables which are on stack.  We should avoid
    accessing stack when stack is corrupted.
    
    This patch also renames function argument in __fortify_fail_abort
    from do_backtrace to need_backtrace to avoid confusion with do_backtrace
    from enum __libc_message_action.
    
    	[BZ #21752]
    	* debug/fortify_fail.c (__fortify_fail_abort): Don't pass down
    	__libc_argv[0] if we aren't doing backtrace.  Rename do_backtrace
    	to need_backtrace.
    	* sysdeps/posix/libc_fatal.c (__libc_message): Don't call
    	__libc_secure_getenv if we aren't doing backtrace.

diff --git a/debug/fortify_fail.c b/debug/fortify_fail.c
index c90d384..a0777ae 100644
--- a/debug/fortify_fail.c
+++ b/debug/fortify_fail.c
@@ -24,13 +24,17 @@ extern char **__libc_argv attribute_hidden;
 
 void
 __attribute__ ((noreturn)) internal_function
-__fortify_fail_abort (_Bool do_backtrace, const char *msg)
+__fortify_fail_abort (_Bool need_backtrace, const char *msg)
 {
-  /* The loop is added only to keep gcc happy.  */
+  /* The loop is added only to keep gcc happy.  Don't pass down
+     __libc_argv[0] if we aren't doing backtrace since __libc_argv[0]
+     may point to the corrupted stack.  */
   while (1)
-    __libc_message (do_backtrace ? (do_abort | do_backtrace) : do_abort,
+    __libc_message (need_backtrace ? (do_abort | do_backtrace) : do_abort,
 		    "*** %s ***: %s terminated\n",
-		    msg, __libc_argv[0] ?: "<unknown>");
+		    msg,
+		    (need_backtrace && __libc_argv[0] != NULL
+		     ? __libc_argv[0] : "<unknown>"));
 }
 
 void
diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c
index 25af8bd..c918919 100644
--- a/sysdeps/posix/libc_fatal.c
+++ b/sysdeps/posix/libc_fatal.c
@@ -75,11 +75,16 @@ __libc_message (enum __libc_message_action action, const char *fmt, ...)
   FATAL_PREPARE;
 #endif
 
-  /* Open a descriptor for /dev/tty unless the user explicitly
-     requests errors on standard error.  */
-  const char *on_2 = __libc_secure_getenv ("LIBC_FATAL_STDERR_");
-  if (on_2 == NULL || *on_2 == '\0')
-    fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
+  /* Don't call __libc_secure_getenv if we aren't doing backtrace, which
+     may access the corrupted stack.  */
+  if ((action & do_backtrace))
+    {
+      /* Open a descriptor for /dev/tty unless the user explicitly
+	 requests errors on standard error.  */
+      const char *on_2 = __libc_secure_getenv ("LIBC_FATAL_STDERR_");
+      if (on_2 == NULL || *on_2 == '\0')
+	fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
+    }
 
   if (fd == -1)
     fd = STDERR_FILENO;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=ba748decd981266d2cc3feb11c9c15d9c1f55478

commit ba748decd981266d2cc3feb11c9c15d9c1f55478
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jul 19 16:53:06 2017 -0700

    tunables: Use direct syscall for access (BZ#21744)
    
    The function maybe_enable_malloc_check, which is called by
    __tunables_init, calls __access_noerrno.  It isn't problem when
    symbol is is in ld.so, which has a special version of __access_noerrno
    without stack protector.  But when glibc is built with stack protector,
    maybe_enable_malloc_check in libc.a can't call the regular version of
    __access_noerrno with stack protector.
    
    This patch changes how Linux defines the __access_noerrno to be an
    inline call instead and thus preventing defining different build
    rules for ld/static and shared.
    
    	H.J. Lu  <hongjiu.lu@intel.com>
    	Adhemerval Zanella  <adhemerval.zanella@linaro.org>
    
    	* elf/dl-tunables.c: Include not-errno.h header.
    	* include/unistd.h (__access_noerrno): Remove definition.
    	* sysdeps/unix/sysv/linux/access.c (__access_noerrno): Likewise.
    	* sysdeps/generic/not-errno.h: New file.
    	* sysdeps/unix/sysv/linux/not-errno.h: Likewise.

diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index 44c160c..231fb8c 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -29,6 +29,8 @@
 #define TUNABLES_INTERNAL 1
 #include "dl-tunables.h"
 
+#include <not-errno.h>
+
 #if TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring
 # define GLIBC_TUNABLES "GLIBC_TUNABLES"
 #endif
diff --git a/include/unistd.h b/include/unistd.h
index 5b2a414..7f1c2cc 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -182,12 +182,5 @@ extern int __getlogin_r_loginuid (char *name, size_t namesize)
 #   include <dl-unistd.h>
 #  endif
 
-#  if IS_IN (rtld) || !defined SHARED
-/* __access variant that does not set errno.  Used in very early initialization
-   code in libc.a and ld.so.  It follows access return semantics (zero for
-   sucess otherwise a value different than 0).  */
-extern __typeof (__access) __access_noerrno attribute_hidden;
-#  endif
-
 # endif
 #endif
diff --git a/sysdeps/generic/not-errno.h b/sysdeps/generic/not-errno.h
new file mode 100644
index 0000000..2aac095
--- /dev/null
+++ b/sysdeps/generic/not-errno.h
@@ -0,0 +1,19 @@
+/* Syscall wrapper that do not set errno.  Generic version.
+   Copyright (C) 2017 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+extern __typeof (__access) __access_noerrno attribute_hidden;
diff --git a/sysdeps/unix/sysv/linux/access.c b/sysdeps/unix/sysv/linux/access.c
index 67e69bd..366b6b6 100644
--- a/sysdeps/unix/sysv/linux/access.c
+++ b/sysdeps/unix/sysv/linux/access.c
@@ -21,21 +21,6 @@
 #include <sysdep-cancel.h>
 
 int
-__access_noerrno (const char *file, int type)
-{
-  int res;
-  INTERNAL_SYSCALL_DECL (err);
-#ifdef __NR_access
-  res = INTERNAL_SYSCALL_CALL (access, err, file, type);
-#else
-  res = INTERNAL_SYSCALL_CALL (faccessat, err, AT_FDCWD, file, type);
-#endif
-  if (INTERNAL_SYSCALL_ERROR_P (res, err))
-    return INTERNAL_SYSCALL_ERRNO (res, err);
-  return 0;
-}
-
-int
 __access (const char *file, int type)
 {
 #ifdef __NR_access
diff --git a/sysdeps/unix/sysv/linux/access.c b/sysdeps/unix/sysv/linux/not-errno.h
similarity index 50%
copy from sysdeps/unix/sysv/linux/access.c
copy to sysdeps/unix/sysv/linux/not-errno.h
index 67e69bd..888bde0 100644
--- a/sysdeps/unix/sysv/linux/access.c
+++ b/sysdeps/unix/sysv/linux/not-errno.h
@@ -1,5 +1,5 @@
-/* Linux implementation for access function.
-   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+/* Syscall wrapper that do not set errno.  Linux version.
+   Copyright (C) 2017 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
@@ -13,35 +13,19 @@
    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
+   License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <fcntl.h>
-#include <unistd.h>
-#include <sysdep-cancel.h>
-
-int
-__access_noerrno (const char *file, int type)
+/* This function is used on maybe_enable_malloc_check (elf/dl-tunables.c)
+   and to avoid having to build/use multiple versions if stack protection
+   in enabled it is defined as inline.  */
+static inline int
+__access_noerrno (const char *pathname, int mode)
 {
-  int res;
   INTERNAL_SYSCALL_DECL (err);
 #ifdef __NR_access
-  res = INTERNAL_SYSCALL_CALL (access, err, file, type);
-#else
-  res = INTERNAL_SYSCALL_CALL (faccessat, err, AT_FDCWD, file, type);
-#endif
-  if (INTERNAL_SYSCALL_ERROR_P (res, err))
-    return INTERNAL_SYSCALL_ERRNO (res, err);
-  return 0;
-}
-
-int
-__access (const char *file, int type)
-{
-#ifdef __NR_access
-  return INLINE_SYSCALL_CALL (access, file, type);
+  return INTERNAL_SYSCALL_CALL (access, err, pathname, mode);
 #else
-  return INLINE_SYSCALL_CALL (faccessat, AT_FDCWD, file, type);
+  return INTERNAL_SYSCALL_CALL (faccessat, err, AT_FDCWD, file, type);
 #endif
 }
-weak_alias (__access, access)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=4e616357a0abb3a13b78b1a8bbbf10b4a055d398

commit 4e616357a0abb3a13b78b1a8bbbf10b4a055d398
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jul 19 12:04:14 2017 -0700

    Compile tst-prelink.c without PIE [BZ #21815]
    
    tst-prelink.c checks for conflict with GLOB_DAT relocation against stdio.
    On i386, there is no GLOB_DAT relocation against stdio with PIE.  We
    should compile tst-prelink.c without PIE.
    
    	[BZ #21815]
    	* elf/Makefile (CFLAGS-tst-prelink.c): New.
    	(LDFLAGS-tst-prelink): Likewise.

diff --git a/elf/Makefile b/elf/Makefile
index e758a4c..d39f4c5 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -356,6 +356,9 @@ update-all-abi: update-all-abi-ld
 
 ifeq ($(have-glob-dat-reloc),yes)
 tests += tst-prelink
+# Don't compile tst-prelink.c with PIE for GLOB_DAT relocation.
+CFLAGS-tst-prelink.c += -fno-pie
+LDFLAGS-tst-prelink = $(no-pie-ldflag)
 ifeq ($(run-built-tests),yes)
 tests-special += $(objpfx)tst-prelink-cmp.out
 endif

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


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