1/*
2 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
3 * Distributed under the terms of the NewOS License.
4 */
5
6
7#include <sys/types.h>
8#include <string.h>
9
10#if !_ASM_MEMCPY
11
12typedef int word;
13
14#define lsize sizeof(word)
15#define lmask (lsize - 1)
16
17
18void*
19memmove(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#if defined(__arm__)
74void* __aeabi_memmove(void* dest, void const* src, size_t count)
75	__attribute__((__alias__("memmove")));
76#endif
77
78#endif
79