xref: /haiku/src/system/libroot/posix/string/memmove.c (revision fef6144999c2fa611f59ee6ffe6dd7999501385c)
1 /*
2 ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
5 
6 #include <sys/types.h>
7 #include <string.h>
8 
9 #if !_ASM_MEMCPY
10 
11 typedef int word;
12 
13 #define lsize sizeof(word)
14 #define lmask (lsize - 1)
15 
16 void *
17 memmove(void *dest, void const *src, size_t count)
18 {
19 	char *d = (char *)dest;
20 	const char *s = (const char *)src;
21 	int len;
22 
23 	if(count == 0 || dest == src)
24 		return dest;
25 
26 	if((long)d < (long)s) {
27 		if(((long)d | (long)s) & lmask) {
28 			// src and/or dest do not align on word boundary
29 			if((((long)d ^ (long)s) & lmask) || (count < lsize))
30 				len = count; // copy the rest of the buffer with the byte mover
31 			else
32 				len = lsize - ((long)d & lmask); // move the ptrs up to a word boundary
33 
34 			count -= len;
35 			for(; len > 0; len--)
36 				*d++ = *s++;
37 		}
38 		for(len = count / lsize; len > 0; len--) {
39 			*(word *)d = *(word *)s;
40 			d += lsize;
41 			s += lsize;
42 		}
43 		for(len = count & lmask; len > 0; len--)
44 			*d++ = *s++;
45 	} else {
46 		d += count;
47 		s += count;
48 		if(((long)d | (long)s) & lmask) {
49 			// src and/or dest do not align on word boundary
50 			if((((long)d ^ (long)s) & lmask) || (count <= lsize))
51 				len = count;
52 			else
53 				len = ((long)d & lmask);
54 
55 			count -= len;
56 			for(; len > 0; len--)
57 				*--d = *--s;
58 		}
59 		for(len = count / lsize; len > 0; len--) {
60 			d -= lsize;
61 			s -= lsize;
62 			*(word *)d = *(word *)s;
63 		}
64 		for(len = count & lmask; len > 0; len--)
65 			*--d = *--s;
66 	}
67 
68 	return dest;
69 }
70 
71 #endif
72 
73