1 // Copyright 2016 The Fuchsia Authors
2 // Copyright (c) 2008 Travis Geiselbrecht
3 //
4 // Use of this source code is governed by a MIT-style
5 // license that can be found in the LICENSE file or at
6 // https://opensource.org/licenses/MIT
7 
8 #include <string.h>
9 #include <sys/types.h>
10 
11 #if !_ASM_MEMMOVE
12 
13 typedef long word;
14 
15 #define lsize sizeof(word)
16 #define lmask (lsize - 1)
17 
18 void *
memmove(void * dest,void const * src,size_t count)19 memmove(void *dest, void const *src, size_t count)
20 {
21     char *d = (char *)dest;
22     const char *s = (const char *)src;
23     int len;
24 
25     if (count == 0 || dest == src)
26         return dest;
27 
28     if ((long)d < (long)s) {
29         if (((long)d | (long)s) & lmask) {
30             // src and/or dest do not align on word boundary
31             if ((((long)d ^ (long)s) & lmask) || (count < lsize))
32                 len = count; // copy the rest of the buffer with the byte mover
33             else
34                 len = lsize - ((long)d & lmask); // move the ptrs up to a word boundary
35 
36             count -= len;
37             for (; len > 0; len--)
38                 *d++ = *s++;
39         }
40         for (len = count / lsize; len > 0; len--) {
41             *(word *)d = *(word *)s;
42             d += lsize;
43             s += lsize;
44         }
45         for (len = count & lmask; len > 0; len--)
46             *d++ = *s++;
47     } else {
48         d += count;
49         s += count;
50         if (((long)d | (long)s) & lmask) {
51             // src and/or dest do not align on word boundary
52             if ((((long)d ^ (long)s) & lmask) || (count <= lsize))
53                 len = count;
54             else
55                 len = ((long)d & lmask);
56 
57             count -= len;
58             for (; len > 0; len--)
59                 *--d = *--s;
60         }
61         for (len = count / lsize; len > 0; len--) {
62             d -= lsize;
63             s -= lsize;
64             *(word *)d = *(word *)s;
65         }
66         for (len = count & lmask; len > 0; len--)
67             *--d = *--s;
68     }
69 
70     return dest;
71 }
72 
73 #endif
74 
75