about summary refs log tree commit diff
path: root/sysdeps/i386/i486
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/i386/i486')
-rw-r--r--sysdeps/i386/i486/bits/string.h30
1 files changed, 28 insertions, 2 deletions
diff --git a/sysdeps/i386/i486/bits/string.h b/sysdeps/i386/i486/bits/string.h
index f810de06ea..e20f037ab7 100644
--- a/sysdeps/i386/i486/bits/string.h
+++ b/sysdeps/i386/i486/bits/string.h
@@ -1,5 +1,5 @@
 /* Optimized, inlined string functions.  i486 version.
-   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999 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
@@ -377,6 +377,30 @@ memchr (__const void *__s, int __c, size_t __n)
 }
 
 
+/* Return pointer to C in S.  */
+#define _HAVE_STRING_ARCH_rawmemchr 1
+__STRING_INLINE void *
+__rawmemchr (const void *__s, int __c)
+{
+  register unsigned long int __d0;
+  register unsigned char *__res;
+  __asm__ __volatile__
+    ("cld\n\t"
+     "repne; scasb\n\t"
+     : "=D" (__res), "=&c" (__d0)
+     : "a" (__c), "0" (__s), "1" (0xffffffff)
+     : "cc");
+  return __res - 1;
+}
+#ifdef __USE_GNU
+__STRING_INLINE void *
+rawmemchr (const void *__s, int __c)
+{
+  return __rawmemchr (__s, __c);
+}
+#endif	/* use GNU */
+
+
 /* Return the length of S.  */
 #define _HAVE_STRING_ARCH_strlen 1
 #define strlen(str) \
@@ -1049,7 +1073,9 @@ __strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
 #define _HAVE_STRING_ARCH_strchr 1
 #define strchr(s, c) \
   (__extension__ (__builtin_constant_p (c)				      \
-		  ? __strchr_c (s, ((c) & 0xff) << 8)			      \
+		  ? ((c) == '\0'					      \
+		     ? (char *) __rawmemchr (s, c)			      \
+		     : __strchr_c (s, ((c) & 0xff) << 8))		      \
 		  : __strchr_g (s, c)))
 
 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);