about summary refs log tree commit diff
path: root/string
diff options
context:
space:
mode:
Diffstat (limited to 'string')
-rw-r--r--string/bits/string2.h62
1 files changed, 59 insertions, 3 deletions
diff --git a/string/bits/string2.h b/string/bits/string2.h
index 3de175d0a8..d9ed80b3b5 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -94,9 +94,65 @@ __STRING2_COPY_TYPE (8);
 /* Set N bytes of S to C.  */
 #ifndef _HAVE_STRING_ARCH_memset
 # define memset(s, c, n) \
-  (__extension__ (__builtin_constant_p (c) && (c) == '\0'		      \
-		  ? ({ void *__s = (s); __bzero (__s, n); __s; })	      \
-		  : memset (s, c, n)))
+  (__extension__ (__builtin_constant_p (n) && (n) <= 16			      \
+		  ? (__builtin_constant_p (c)				      \
+		     ? __memset_gc (s, (c) * 0x01010101, n)		      \
+		     : __memset_gc (s, (n) == 1 ? (c) : (c) * 0x01010101, n)) \
+		  : (__builtin_constant_p (c) && (c) == '\0'		      \
+		     ? ({ void *__s = (s); __bzero (__s, n); __s; })	      \
+		     : memset (s, c, n))))
+
+#define __memset_gc(s, c, n) \
+  ({ void *__s = (s);							      \
+     __uint32_t *__ts = (__uint32_t *) __s;				      \
+     									      \
+     /* This `switch' statement will be removed at compile-time.  */	      \
+     switch (n)								      \
+       {								      \
+       case 15:								      \
+	 *__ts++ = c;							      \
+       case 11:								      \
+	 *__ts++ = c;							      \
+       case 7:								      \
+	 *__ts++ = c;							      \
+       case 3:								      \
+	 *((__uint16_t *) __ts)++ = c;					      \
+	 *((__uint8_t *) __ts) = c;					      \
+	 break;								      \
+									      \
+       case 14:								      \
+	 *__ts++ = c;							      \
+       case 10:								      \
+	 *__ts++ = c;							      \
+       case 6:								      \
+	 *__ts++ = c;							      \
+       case 2:								      \
+	 *((__uint16_t *) __ts) = c;					      \
+	 break;								      \
+									      \
+       case 13:								      \
+	 *__ts++ = c;							      \
+       case 9:								      \
+	 *__ts++ = c;							      \
+       case 5:								      \
+	 *__ts++ = c;							      \
+       case 1:								      \
+	 *((__uint8_t *) __ts) = c;					      \
+	 break;								      \
+									      \
+       case 16:								      \
+	 *__ts++ = c;							      \
+       case 12:								      \
+	 *__ts++ = c;							      \
+       case 8:								      \
+	 *__ts++ = c;							      \
+       case 4:								      \
+	 *__ts = c;							      \
+       case 0:								      \
+	 break;								      \
+       }								      \
+									      \
+     __s; })
 #endif