reenable word-at-at-time copying in memmove
authorRich Felker <dalias@aerifal.cx>
Mon, 10 Sep 2012 22:16:11 +0000 (18:16 -0400)
committerRich Felker <dalias@aerifal.cx>
Mon, 10 Sep 2012 22:16:11 +0000 (18:16 -0400)
before restrict was added, memove called memcpy for forward copies and
used a byte-at-a-time loop for reverse copies. this was changed to
avoid invoking UB now that memcpy has an undefined copying order,
making memmove considerably slower.

performance is still rather bad, so I'll be adding asm soon.

src/string/memmove.c

index 9153a64476a97a64bfc1e0614276f91e18ebea73..27f670e1a31fe860ff6ce17a453559ef42706aeb 100644 (file)
@@ -1,13 +1,36 @@
 #include <string.h>
+#include <stdint.h>
+
+#define WT size_t
+#define WS (sizeof(WT))
 
 void *memmove(void *dest, const void *src, size_t n)
 {
        char *d = dest;
        const char *s = src;
+
        if (d==s) return d;
-       if ((size_t)(d-s) < n)
-               while (n--) d[n] = s[n];
-       else
-               while (n--) *d++ = *s++;
+       if (s+n <= d || d+n <= s) return memcpy(d, s, n);
+
+       if (d<s) {
+               if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
+                       while ((uintptr_t)d % WS) {
+                               if (!n--) return dest;
+                               *d++ = *s++;
+                       }
+                       for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s;
+               }
+               for (; n; n--) *d++ = *s++;
+       } else {
+               if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
+                       while ((uintptr_t)(d+n) % WS) {
+                               if (!n--) return dest;
+                               d[n] = s[n];
+                       }
+                       while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n);
+               }
+               while (n) n--, d[n] = s[n];
+       }
+
        return dest;
 }