xref: /haiku/src/system/libroot/posix/string/memmove.c (revision 9642f7705b27e5c270c15fa526d14e1848c2c27d)
15af32e75SAxel Dörfler /*
236b89f8fSIngo Weinhold  * Copyright 2001, Travis Geiselbrecht. All rights reserved.
336b89f8fSIngo Weinhold  * Distributed under the terms of the NewOS License.
45af32e75SAxel Dörfler  */
55af32e75SAxel Dörfler 
636b89f8fSIngo Weinhold 
75af32e75SAxel Dörfler #include <sys/types.h>
85af32e75SAxel Dörfler #include <string.h>
95af32e75SAxel Dörfler 
105af32e75SAxel Dörfler #if !_ASM_MEMCPY
115af32e75SAxel Dörfler 
125af32e75SAxel Dörfler typedef int word;
135af32e75SAxel Dörfler 
145af32e75SAxel Dörfler #define lsize sizeof(word)
155af32e75SAxel Dörfler #define lmask (lsize - 1)
165af32e75SAxel Dörfler 
1736b89f8fSIngo Weinhold 
185af32e75SAxel Dörfler void*
memmove(void * dest,void const * src,size_t count)195af32e75SAxel Dörfler memmove(void* dest, void const* src, size_t count)
205af32e75SAxel Dörfler {
215af32e75SAxel Dörfler 	char* d = (char*)dest;
225af32e75SAxel Dörfler 	const char* s = (const char*)src;
235af32e75SAxel Dörfler 	int len;
245af32e75SAxel Dörfler 
255af32e75SAxel Dörfler 	if (count == 0 || dest == src)
265af32e75SAxel Dörfler 		return dest;
275af32e75SAxel Dörfler 
285af32e75SAxel Dörfler 	if ((long)d < (long)s) {
295af32e75SAxel Dörfler 		if (((long)d | (long)s) & lmask) {
305af32e75SAxel Dörfler 			// src and/or dest do not align on word boundary
315af32e75SAxel Dörfler 			if ((((long)d ^ (long)s) & lmask) || (count < lsize))
325af32e75SAxel Dörfler 				len = count; // copy the rest of the buffer with the byte mover
335af32e75SAxel Dörfler 			else
345af32e75SAxel Dörfler 				len = lsize - ((long)d & lmask); // move the ptrs up to a word boundary
355af32e75SAxel Dörfler 
365af32e75SAxel Dörfler 			count -= len;
375af32e75SAxel Dörfler 			for (; len > 0; len--)
385af32e75SAxel Dörfler 				*d++ = *s++;
395af32e75SAxel Dörfler 		}
405af32e75SAxel Dörfler 		for (len = count / lsize; len > 0; len--) {
415af32e75SAxel Dörfler 			*(word*)d = *(word*)s;
425af32e75SAxel Dörfler 			d += lsize;
435af32e75SAxel Dörfler 			s += lsize;
445af32e75SAxel Dörfler 		}
455af32e75SAxel Dörfler 		for (len = count & lmask; len > 0; len--)
465af32e75SAxel Dörfler 			*d++ = *s++;
475af32e75SAxel Dörfler 	} else {
485af32e75SAxel Dörfler 		d += count;
495af32e75SAxel Dörfler 		s += count;
505af32e75SAxel Dörfler 		if (((long)d | (long)s) & lmask) {
515af32e75SAxel Dörfler 			// src and/or dest do not align on word boundary
525af32e75SAxel Dörfler 			if ((((long)d ^ (long)s) & lmask) || (count <= lsize))
535af32e75SAxel Dörfler 				len = count;
545af32e75SAxel Dörfler 			else
555af32e75SAxel Dörfler 				len = ((long)d & lmask);
565af32e75SAxel Dörfler 
575af32e75SAxel Dörfler 			count -= len;
585af32e75SAxel Dörfler 			for (; len > 0; len--)
595af32e75SAxel Dörfler 				*--d = *--s;
605af32e75SAxel Dörfler 		}
615af32e75SAxel Dörfler 		for (len = count / lsize; len > 0; len--) {
625af32e75SAxel Dörfler 			d -= lsize;
635af32e75SAxel Dörfler 			s -= lsize;
645af32e75SAxel Dörfler 			*(word*)d = *(word*)s;
655af32e75SAxel Dörfler 		}
665af32e75SAxel Dörfler 		for (len = count & lmask; len > 0; len--)
675af32e75SAxel Dörfler 			*--d = *--s;
685af32e75SAxel Dörfler 	}
695af32e75SAxel Dörfler 
705af32e75SAxel Dörfler 	return dest;
715af32e75SAxel Dörfler }
725af32e75SAxel Dörfler 
73*9642f770SAlexander von Gluck IV #if defined(__arm__)
7415d594ccSJonathan Schleifer void* __aeabi_memmove(void* dest, void const* src, size_t count)
7515d594ccSJonathan Schleifer 	__attribute__((__alias__("memmove")));
7615d594ccSJonathan Schleifer #endif
7715d594ccSJonathan Schleifer 
785af32e75SAxel Dörfler #endif
79