[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r8765 - in /fsf/trunk/libc: ./ nptl/ nptl/sysdeps/unix/sysv/linux/x86_64/ nptl/sysdeps/x86_64/ sysdeps/i386/i686/multiarch/ ...



Author: eglibc
Date: Wed Aug  5 00:04:14 2009
New Revision: 8765

Log:
Import glibc-mainline for 2009-08-05

Added:
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcasestr-c.c
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcasestr.c
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcspn-c.c
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcspn.S
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/strlen.S
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/strpbrk-c.c
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/strpbrk.S
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/strspn-c.c
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/strspn.S
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/strstr-c.c
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/strstr.c
Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/nptl/ChangeLog
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
    fsf/trunk/libc/nptl/sysdeps/x86_64/tcb-offsets.sym
    fsf/trunk/libc/sysdeps/i386/i686/multiarch/Makefile
    fsf/trunk/libc/sysdeps/x86_64/multiarch/strcspn-c.c
    fsf/trunk/libc/sysdeps/x86_64/multiarch/strspn-c.c

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Wed Aug  5 00:04:14 2009
@@ -1,3 +1,33 @@
+2009-08-03  H.J. Lu  <hongjiu.lu@xxxxxxxxx>
+
+	* sysdeps/i386/i686/multiarch/strcspn.S: Add comments for no
+	hidden IFUNC functions.
+	* sysdeps/i386/i686/multiarch/strspn.S: Likewise.
+
+	* sysdeps/i386/i686/multiarch/strlen.S: New file.
+
+	* sysdeps/i386/i686/multiarch/Makefile [subdir=string]
+	(sysdep_routines): Add strcspn-c, strpbrk-c, strspn-c, strstr-c, and
+	strcasestr-c.
+	(CFLAGS-strcspn-c.c): Define.
+	(CFLAGS-strpbrk-c.c): Define.
+	(CFLAGS-strspn-c.c): Define.
+	(CFLAGS-strstr.c): Define.
+	(CFLAGS-strcasestr.c): Define.
+	* sysdeps/i386/i686/multiarch/strcspn-c.c: New file.
+	* sysdeps/i386/i686/multiarch/strcspn.S: New file.
+	* sysdeps/i386/i686/multiarch/strpbrk-c.c: New file.
+	* sysdeps/i386/i686/multiarch/strpbrk.S: New file.
+	* sysdeps/i386/i686/multiarch/strspn-c.c: New file.
+	* sysdeps/i386/i686/multiarch/strspn.S: New file.
+	* sysdeps/i386/i686/multiarch/strstr-c.c: New file.
+	* sysdeps/i386/i686/multiarch/strstr.c: New file.
+	* sysdeps/i386/i686/multiarch/strcasestr-c.c: New file.
+	* sysdeps/i386/i686/multiarch/strcasestr.c: New file.
+	* sysdeps/x86_64/multiarch/strcspn-c.c (STRCSPN_SSE42): Use
+	-16L instead of 0xfffffffffffffff0L.
+	* sysdeps/x86_64/multiarch/strspn-c.c (__strspn_sse42): Likewise.
+
 2009-08-02  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	* sysdeps/i386/configure.in: Add test for <cpuid.h>.

Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Wed Aug  5 00:04:14 2009
@@ -1,3 +1,15 @@
+2009-08-04  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* sysdeps/unix/sysv/linux/x86_64/cancellation.S: New file.
+	* sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S: New file.
+	* sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S: New file.
+	* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO): Optimize
+	since we can assume the special __*_{en,dis}able_asynccancel
+	functions.
+	(PUSHARGS_*, POPARGS_*, SAVESTK_*, RESTSTK_*): Removed.
+	* sysdeps/x86_64/tcb-offsets.sym: Add cancellation-related bits
+	and PTHREAD_CANCELED.
+
 2009-07-31  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	* descr.h: Better definition of *_BITMASK macros for cancellation.

Added: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S (added)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S Wed Aug  5 00:04:14 2009
@@ -1,0 +1,114 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2009.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tcb-offsets.h>
+#include <kernel-features.h>
+
+#ifdef IS_IN_libpthread
+# ifdef SHARED
+#  define __pthread_unwind __GI___pthread_unwind
+# endif
+#else
+# ifndef SHARED
+	.weak __pthread_unwind
+# endif
+#endif
+
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+	movl	$(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
+#else
+# if FUTEX_WAIT == 0
+#  define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+	movl	%fs:PRIVATE_FUTEX, reg
+# else
+#  define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+	movl	%fs:PRIVATE_FUTEX, reg ; \
+	orl	$FUTEX_WAIT, reg
+# endif
+#endif
+
+/* It is crucial that the functions in this file don't modify registers
+   other than %rax and %r11.  The syscall wrapper code depends on this
+   because it doesn't explicitly save the other registers which hold
+   relevant values.  */
+	.text
+
+	.hidden __pthread_enable_asynccancel
+ENTRY(__pthread_enable_asynccancel)
+	movl	%fs:CANCELHANDLING, %eax
+2:	movl	%eax, %r11d
+	orl	$TCB_CANCELTYPE_BITMASK, %r11d
+	cmpl	%eax, %r11d
+	je	1f
+
+	lock
+	cmpxchgl %r11d, %fs:CANCELHANDLING
+	jnz	2b
+
+	andl	$(TCB_CANCELSTATE_BITMASK|TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK|TCB_EXITING_BITMASK|TCB_CANCEL_RESTMASK|TCB_TERMINATED_BITMASK), %r11d
+	cmpl	$(TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK), %r11d
+	je	3f
+
+1:	ret
+
+3:	movq	$TCB_PTHREAD_CANCELED, %fs:RESULT
+	lock
+	orl	$TCB_EXITING_BITMASK, %fs:CANCELHANDLING
+	movq	%fs:CLEANUP_JMP_BUF, %rdi
+#ifdef SHARED
+	call	__pthread_unwind@PLT
+#else
+	call	__pthread_unwind
+#endif
+	hlt
+END(__pthread_enable_asynccancel)
+
+
+	.hidden __pthread_disable_asynccancel
+ENTRY(__pthread_disable_asynccancel)
+	testl	$TCB_CANCELTYPE_BITMASK, %edi
+	jnz	1f
+
+	movl	%fs:CANCELHANDLING, %eax
+2:	movl	%eax, %r11d
+	andl	$~TCB_CANCELTYPE_BITMASK, %r11d
+	lock
+	cmpxchgl %r11d, %fs:CANCELHANDLING
+	jnz	2b
+
+3:	movl	%r11d, %eax
+	andl	$(TCB_CANCELING_BITMASK|TCB_CANCELED_BITMASK), %eax
+	cmpl	$TCB_CANCELING_BITMASK, %eax
+	je	4f
+1:	ret
+
+	/* Performance doesn't matter in this loop.  We will
+	   delay until the thread is canceled.  And we will unlikely
+	   enter the loop twice.  */
+4:	movq	%fs:0, %rdi
+	movl	$__NR_futex, %eax
+	xorq	%r10, %r10
+	addq	$CANCELHANDLING, %rdi
+	LOAD_PRIVATE_FUTEX_WAIT (%esi)
+	syscall
+	jmp	3b
+END(__pthread_disable_asynccancel)

Added: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S (added)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S Wed Aug  5 00:04:14 2009
@@ -1,0 +1,22 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2009.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define __pthread_enable_asynccancel __libc_enable_asynccancel
+#define __pthread_disable_asynccancel __libc_disable_asynccancel
+#include "cancellation.S"

Added: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S (added)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S Wed Aug  5 00:04:14 2009
@@ -1,0 +1,22 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2009.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define __pthread_enable_asynccancel __librt_enable_asynccancel
+#define __pthread_disable_asynccancel __librt_disable_asynccancel
+#include "cancellation.S"

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h Wed Aug  5 00:04:14 2009
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2006, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@xxxxxxxxxx>, 2002.
 
@@ -25,6 +25,10 @@
 
 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
 
+/* The code to disable cancellation depends on the fact that the called
+   functions are special.  They don't modify registers other than %rax
+   and %r11 if they return.  Therefore we don't have to preserve other
+   registers around these calls.  */
 # undef PSEUDO
 # define PSEUDO(name, syscall_name, args)				      \
   .text;								      \
@@ -40,59 +44,22 @@
     ret;								      \
   .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	      \
   L(pseudo_cancel):							      \
-    /* Save registers that might get destroyed.  */			      \
-    SAVESTK_##args							      \
-    PUSHARGS_##args							      \
+    /* We always have to align the stack before calling a function.  */	      \
+    subq $8, %rsp; cfi_adjust_cfa_offset (8);				      \
     CENABLE								      \
-    /* Restore registers.  */						      \
-    POPARGS_##args							      \
     /* The return value from CENABLE is argument for CDISABLE.  */	      \
     movq %rax, (%rsp);							      \
-    movl $SYS_ify (syscall_name), %eax;					      \
-    syscall;								      \
+    DO_CALL (syscall_name, args);					      \
     movq (%rsp), %rdi;							      \
     /* Save %rax since it's the error code from the syscall.  */	      \
-    movq %rax, 8(%rsp);							      \
+    movq %rax, %rdx;							      \
     CDISABLE								      \
-    movq 8(%rsp), %rax;							      \
-    RESTSTK_##args							      \
+    movq %rdx, %rax;							      \
+    addq $8,%rsp; cfi_adjust_cfa_offset (-8);				      \
     cmpq $-4095, %rax;							      \
     jae SYSCALL_ERROR_LABEL;						      \
   L(pseudo_end):
 
-
-# define PUSHARGS_0	/* Nothing.  */
-# define PUSHARGS_1	PUSHARGS_0 movq %rdi, 8(%rsp);
-# define PUSHARGS_2	PUSHARGS_1 movq %rsi, 16(%rsp);
-# define PUSHARGS_3	PUSHARGS_2 movq %rdx, 24(%rsp);
-# define PUSHARGS_4	PUSHARGS_3 movq %rcx, 32(%rsp);
-# define PUSHARGS_5	PUSHARGS_4 movq %r8, 40(%rsp);
-# define PUSHARGS_6	PUSHARGS_5 movq %r9, 48(%rsp);
-
-# define POPARGS_0	/* Nothing.  */
-# define POPARGS_1	POPARGS_0 movq 8(%rsp), %rdi;
-# define POPARGS_2	POPARGS_1 movq 16(%rsp), %rsi;
-# define POPARGS_3	POPARGS_2 movq 24(%rsp), %rdx;
-# define POPARGS_4	POPARGS_3 movq 32(%rsp), %r10;
-# define POPARGS_5	POPARGS_4 movq 40(%rsp), %r8;
-# define POPARGS_6	POPARGS_5 movq 48(%rsp), %r9;
-
-/* We always have to align the stack before calling a function.  */
-# define SAVESTK_0	subq $24, %rsp; cfi_adjust_cfa_offset (24);
-# define SAVESTK_1	SAVESTK_0
-# define SAVESTK_2	SAVESTK_1
-# define SAVESTK_3	subq $40, %rsp; cfi_adjust_cfa_offset (40);
-# define SAVESTK_4	SAVESTK_3
-# define SAVESTK_5	subq $56, %rsp; cfi_adjust_cfa_offset (56);
-# define SAVESTK_6	SAVESTK_5
-
-# define RESTSTK_0	addq $24,%rsp; cfi_adjust_cfa_offset (-24);
-# define RESTSTK_1	RESTSTK_0
-# define RESTSTK_2	RESTSTK_1
-# define RESTSTK_3	addq $40, %rsp; cfi_adjust_cfa_offset (-40);
-# define RESTSTK_4	RESTSTK_3
-# define RESTSTK_5	addq $56, %rsp; cfi_adjust_cfa_offset (-56);
-# define RESTSTK_6	RESTSTK_5
 
 # ifdef IS_IN_libpthread
 #  define CENABLE	call __pthread_enable_asynccancel;

Modified: fsf/trunk/libc/nptl/sysdeps/x86_64/tcb-offsets.sym
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/x86_64/tcb-offsets.sym (original)
+++ fsf/trunk/libc/nptl/sysdeps/x86_64/tcb-offsets.sym Wed Aug  5 00:04:14 2009
@@ -16,3 +16,13 @@
 PRIVATE_FUTEX		offsetof (tcbhead_t, private_futex)
 #endif
 RTLD_SAVESPACE_SSE	offsetof (tcbhead_t, rtld_savespace_sse)
+
+-- Not strictly offsets, but these values are also used in the TCB.
+TCB_CANCELSTATE_BITMASK	 CANCELSTATE_BITMASK
+TCB_CANCELTYPE_BITMASK	 CANCELTYPE_BITMASK
+TCB_CANCELING_BITMASK	 CANCELING_BITMASK
+TCB_CANCELED_BITMASK	 CANCELED_BITMASK
+TCB_EXITING_BITMASK	 EXITING_BITMASK
+TCB_CANCEL_RESTMASK	 CANCEL_RESTMASK
+TCB_TERMINATED_BITMASK	 TERMINATED_BITMASK
+TCB_PTHREAD_CANCELED	 PTHREAD_CANCELED

Modified: fsf/trunk/libc/sysdeps/i386/i686/multiarch/Makefile
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/Makefile (original)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/Makefile Wed Aug  5 00:04:14 2009
@@ -2,3 +2,14 @@
 aux += init-arch
 gen-as-const-headers += ifunc-defines.sym
 endif
+
+ifeq ($(subdir),string)
+ifeq (yes,$(config-cflags-sse4))
+sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c
+CFLAGS-strcspn-c.c += -msse4
+CFLAGS-strpbrk-c.c += -msse4
+CFLAGS-strspn-c.c += -msse4
+CFLAGS-strstr.c += -msse4
+CFLAGS-strcasestr.c += -msse4
+endif
+endif

Added: fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcasestr-c.c
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcasestr-c.c (added)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcasestr-c.c Wed Aug  5 00:04:14 2009
@@ -1,0 +1,2 @@
+#define __strcasestr_sse2 __strcasestr_ia32
+#include <sysdeps/x86_64/multiarch/strcasestr-c.c>

Added: fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcasestr.c
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcasestr.c (added)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcasestr.c Wed Aug  5 00:04:14 2009
@@ -1,0 +1,1 @@
+#include <sysdeps/x86_64/multiarch/strcasestr.c>

Added: fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcspn-c.c
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcspn-c.c (added)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcspn-c.c Wed Aug  5 00:04:14 2009
@@ -1,0 +1,2 @@
+#define __strcspn_sse2 __strcspn_ia32
+#include <sysdeps/x86_64/multiarch/strcspn-c.c>

Added: fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcspn.S
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcspn.S (added)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/strcspn.S Wed Aug  5 00:04:14 2009
@@ -1,0 +1,99 @@
+/* Multiple versions of strcspn
+   Copyright (C) 2009 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <config.h>
+
+#ifdef HAVE_SSE4_SUPPORT
+
+#include <sysdep.h>
+#include <ifunc-defines.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) && !defined NOT_IN_libc
+	.section	.gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
+	.globl	__i686.get_pc_thunk.bx
+	.hidden	__i686.get_pc_thunk.bx
+	.p2align 4
+	.type	__i686.get_pc_thunk.bx,@function
+__i686.get_pc_thunk.bx:
+	movl	(%esp), %ebx
+	ret
+
+	.text
+ENTRY(STRCSPN)
+	.type	STRCSPN, @gnu_indirect_function
+	pushl	%ebx
+	cfi_adjust_cfa_offset (4)
+	cfi_rel_offset (ebx, 0)
+	call	__i686.get_pc_thunk.bx
+	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
+	cmpl	$0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx)
+	jne	1f
+	call	__init_cpu_features
+1:	leal	STRCSPN_IA32@GOTOFF(%ebx), %eax
+	testl	$(1<<20), CPUID_OFFSET+COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET+__cpu_features@GOTOFF(%ebx)
+	jz	2f
+	leal	STRCSPN_SSE42@GOTOFF(%ebx), %eax
+2:	popl	%ebx
+	cfi_adjust_cfa_offset (-4);
+	cfi_restore (ebx)
+	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
+
+#endif /* HAVE_SSE4_SUPPORT */
+
+#ifdef USE_AS_STRPBRK
+#include "../../strpbrk.S"
+#else
+#include "../../strcspn.S"
+#endif

Added: fsf/trunk/libc/sysdeps/i386/i686/multiarch/strlen.S
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/strlen.S (added)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/strlen.S Wed Aug  5 00:04:14 2009
@@ -1,0 +1,154 @@
+/* Multiple versions of strlen
+   Copyright (C) 2009 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <ifunc-defines.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 && !defined NOT_IN_libc
+	.section	.gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
+	.globl	__i686.get_pc_thunk.bx
+	.hidden	__i686.get_pc_thunk.bx
+	.p2align 4
+	.type	__i686.get_pc_thunk.bx,@function
+__i686.get_pc_thunk.bx:
+	movl	(%esp), %ebx
+	ret
+
+	.text
+ENTRY(strlen)
+	.type	strlen, @gnu_indirect_function
+	pushl	%ebx
+	cfi_adjust_cfa_offset (4)
+	cfi_rel_offset (ebx, 0)
+	call	__i686.get_pc_thunk.bx
+	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
+	cmpl	$0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx)
+	jne	1f
+	call	__init_cpu_features
+1:	leal	__strlen_ia32@GOTOFF(%ebx), %eax
+	testl	$(1<<26), CPUID_OFFSET+COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET+__cpu_features@GOTOFF(%ebx)
+	jz	2f
+	leal	__strlen_sse2@GOTOFF(%ebx), %eax
+2:	popl	%ebx
+	cfi_adjust_cfa_offset (-4);
+	cfi_restore (ebx)
+	ret
+END(strlen)
+
+#define CFI_POP(REG)						\
+  cfi_adjust_cfa_offset (-4);					\
+  cfi_restore (REG)
+
+#define RETURN		popl %esi; CFI_POP (esi); ret
+
+	.text
+ENTRY (__strlen_sse2)
+/*
+ * This implementation uses SSE instructions to compare up to 16 bytes
+ * at a time looking for the end of string (null char).
+ */
+	pushl	%esi
+	cfi_adjust_cfa_offset (4)
+	cfi_rel_offset (%esi, 0)
+	mov	8(%esp), %eax
+	mov	%eax, %ecx
+	pxor	%xmm0, %xmm0		/* 16 null chars */
+	mov	%eax, %esi
+	and	$15, %ecx
+	jz	1f			/* string is 16 byte aligned */
+
+	/*
+	* Unaligned case. Round down to 16-byte boundary before comparing
+	* 16 bytes for a null char. The code then compensates for any extra chars
+	* preceding the start of the string.
+	*/
+	and	$-16, %esi
+
+	pcmpeqb	(%esi), %xmm0
+	lea	16(%eax), %esi
+	pmovmskb %xmm0, %edx
+
+	shr	%cl, %edx		/* Compensate for bytes preceding the string */
+	test	%edx, %edx
+	jnz	2f
+	sub	%ecx, %esi		/* no null, adjust to next 16-byte boundary */
+	pxor	%xmm0, %xmm0		/* clear xmm0, may have been changed... */
+
+	.p2align 4
+1:					/* 16 byte aligned */
+	pcmpeqb	(%esi), %xmm0		/* look for null bytes */
+	pmovmskb %xmm0, %edx		/* move each byte mask of %xmm0 to edx */
+
+	add	$16, %esi		/* prepare to search next 16 bytes */
+	test	%edx, %edx		/* if no null byte, %edx must be 0 */
+	jnz	2f			/* found a null */
+
+	pcmpeqb	(%esi), %xmm0
+	pmovmskb %xmm0, %edx
+	add	$16, %esi
+	test	%edx, %edx
+	jnz	2f
+
+	pcmpeqb	(%esi), %xmm0
+	pmovmskb %xmm0, %edx
+	add	$16, %esi
+	test	%edx, %edx
+	jnz	2f
+
+	pcmpeqb	(%esi), %xmm0
+	pmovmskb %xmm0, %edx
+	add	$16, %esi
+	test	%edx, %edx
+	jz	1b
+
+2:
+	neg	%eax
+	lea	-16(%eax, %esi), %eax	/* calculate exact offset */
+	bsf	%edx, %ecx		/* Least significant 1 bit is index of null */
+	add	%ecx, %eax
+	popl	%esi
+	cfi_adjust_cfa_offset (-4)
+	cfi_restore (%esi)
+	ret
+
+END (__strlen_sse2)
+
+# 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"

Added: fsf/trunk/libc/sysdeps/i386/i686/multiarch/strpbrk-c.c
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/strpbrk-c.c (added)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/strpbrk-c.c Wed Aug  5 00:04:14 2009
@@ -1,0 +1,2 @@
+#define __strpbrk_sse2 __strpbrk_ia32
+#include <sysdeps/x86_64/multiarch/strpbrk-c.c>

Added: fsf/trunk/libc/sysdeps/i386/i686/multiarch/strpbrk.S
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/strpbrk.S (added)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/strpbrk.S Wed Aug  5 00:04:14 2009
@@ -1,0 +1,3 @@
+#define STRCSPN strpbrk
+#define USE_AS_STRPBRK
+#include "strcspn.S"

Added: fsf/trunk/libc/sysdeps/i386/i686/multiarch/strspn-c.c
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/strspn-c.c (added)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/strspn-c.c Wed Aug  5 00:04:14 2009
@@ -1,0 +1,2 @@
+#define __strspn_sse2 __strspn_ia32
+#include <sysdeps/x86_64/multiarch/strspn-c.c>

Added: fsf/trunk/libc/sysdeps/i386/i686/multiarch/strspn.S
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/strspn.S (added)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/strspn.S Wed Aug  5 00:04:14 2009
@@ -1,0 +1,80 @@
+/* Multiple versions of strspn
+   Copyright (C) 2009 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <config.h>
+
+#ifdef HAVE_SSE4_SUPPORT
+
+#include <sysdep.h>
+#include <ifunc-defines.h>
+
+/* Define multiple versions only for the definition in libc.  */
+#ifndef NOT_IN_libc
+	.section	.gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
+	.globl	__i686.get_pc_thunk.bx
+	.hidden	__i686.get_pc_thunk.bx
+	.p2align 4
+	.type	__i686.get_pc_thunk.bx,@function
+__i686.get_pc_thunk.bx:
+	movl	(%esp), %ebx
+	ret
+
+	.text
+ENTRY(strspn)
+	.type	strspn, @gnu_indirect_function
+	pushl	%ebx
+	cfi_adjust_cfa_offset (4)
+	cfi_rel_offset (ebx, 0)
+	call	__i686.get_pc_thunk.bx
+	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
+	cmpl	$0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx)
+	jne	1f
+	call	__init_cpu_features
+1:	leal	__strspn_ia32@GOTOFF(%ebx), %eax
+	testl	$(1<<20), CPUID_OFFSET+COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET+__cpu_features@GOTOFF(%ebx)
+	jz	2f
+	leal	__strspn_sse42@GOTOFF(%ebx), %eax
+2:	popl	%ebx
+	cfi_adjust_cfa_offset (-4);
+	cfi_restore (ebx)
+	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
+
+#endif /* HAVE_SSE4_SUPPORT */
+
+#include "../../strspn.S"

Added: fsf/trunk/libc/sysdeps/i386/i686/multiarch/strstr-c.c
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/strstr-c.c (added)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/strstr-c.c Wed Aug  5 00:04:14 2009
@@ -1,0 +1,12 @@
+#include "init-arch.h"
+
+#define STRSTR __strstr_ia32
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name) \
+  __hidden_ver1 (__strstr_ia32, __GI_strstr, __strstr_ia32);
+
+#include "string/strstr.c"
+
+extern char *__strstr_sse42 (const char *, const char *);
+
+libc_ifunc (strstr, HAS_SSE4_2 ? __strstr_sse42 : __strstr_ia32);

Added: fsf/trunk/libc/sysdeps/i386/i686/multiarch/strstr.c
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i686/multiarch/strstr.c (added)
+++ fsf/trunk/libc/sysdeps/i386/i686/multiarch/strstr.c Wed Aug  5 00:04:14 2009
@@ -1,0 +1,1 @@
+#include <sysdeps/x86_64/multiarch/strstr.c>

Modified: fsf/trunk/libc/sysdeps/x86_64/multiarch/strcspn-c.c
==============================================================================
--- fsf/trunk/libc/sysdeps/x86_64/multiarch/strcspn-c.c (original)
+++ fsf/trunk/libc/sysdeps/x86_64/multiarch/strcspn-c.c Wed Aug  5 00:04:14 2009
@@ -90,7 +90,7 @@
   if (offset != 0)
     {
       /* Load masks.  */
-      aligned = (const char *) ((size_t) a & 0xfffffffffffffff0L);
+      aligned = (const char *) ((size_t) a & -16L);
       __m128i mask0 = _mm_load_si128 ((__m128i *) aligned);
 
       switch (offset)
@@ -229,7 +229,7 @@
   if (offset != 0)
     {
       /* Check partial string.  */
-      aligned = (const char *) ((size_t) s & 0xfffffffffffffff0L);
+      aligned = (const char *) ((size_t) s & -16L);
       __m128i value = _mm_load_si128 ((__m128i *) aligned);
 
       switch (offset)

Modified: fsf/trunk/libc/sysdeps/x86_64/multiarch/strspn-c.c
==============================================================================
--- fsf/trunk/libc/sysdeps/x86_64/multiarch/strspn-c.c (original)
+++ fsf/trunk/libc/sysdeps/x86_64/multiarch/strspn-c.c Wed Aug  5 00:04:14 2009
@@ -68,7 +68,7 @@
   if (offset != 0)
     {
       /* Load masks.  */
-      aligned = (const char *) ((size_t) a & 0xfffffffffffffff0L);
+      aligned = (const char *) ((size_t) a & -16L);
       __m128i mask0 = _mm_load_si128 ((__m128i *) aligned);
 
       switch (offset)
@@ -207,7 +207,7 @@
   if (offset != 0)
     {
       /* Check partial string.  */
-      aligned = (const char *) ((size_t) s & 0xfffffffffffffff0L);
+      aligned = (const char *) ((size_t) s & -16L);
       __m128i value = _mm_load_si128 ((__m128i *) aligned);
 
       switch (offset)