1 /*-
2  * Copyright (c) 2007
3  *	Thorsten Glaser <tg@mirbsd.de>
4  *
5  * Provided that these terms and disclaimer and all copyright notices
6  * are retained or reproduced in an accompanying document, permission
7  * is granted to deal in this work without restriction, including un-
8  * limited rights to use, publicly perform, distribute, sell, modify,
9  * merge, give away, or sublicence.
10  *
11  * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
12  * the utmost extent permitted by applicable law, neither express nor
13  * implied; without malicious intent or gross negligence. In no event
14  * may a licensor, author or contributor be held liable for indirect,
15  * direct, other damage, loss, or other issues arising in any way out
16  * of dealing in the work, even if advised of the possibility of such
17  * damage or existence of a defect, except proven that it results out
18  * of said person's immediate fault when using the work as intended.
19  */
20 
21 #include <stdint.h>
22 #include <string.h>
23 
24 __RCSID("$MirOS: src/lib/libc/string/bcopy.c,v 1.8 2007/08/08 20:57:41 tg Exp $");
25 
26 /* this is the basic copy data type, should be fastest */
27 typedef unsigned long mword;
28 
29 #define mbytes	sizeof (mword)
30 #define mmask	(mbytes - 1)
31 
32 #ifdef MEMCOPY
33 #define MEMMOVE
34 #define memmove	memcpy
35 #endif
36 
37 #ifdef MEMMOVE
38 void *
memmove(void * dst,const void * src,size_t len)39 memmove(void *dst, const void *src, size_t len)
40 #else
41 void
42 bcopy(const void *src, void *dst, size_t len)
43 #endif
44 {
45 	const uint8_t *s = src;
46 	uint8_t *d = dst;
47 	size_t n;
48 	intptr_t cp;
49 
50 	if (len == 0 || dst == src)
51 		goto done;
52 
53 	if ((intptr_t)dst < (intptr_t)src) {
54 		/* copy forward */
55 		if ((((cp = (intptr_t)s) | (intptr_t)d) & mmask) &&
56 		    (((cp ^ (intptr_t)d) & mmask) == 0) && len >= mbytes) {
57 			/* low bits match: first align then copy entire words */
58 			n = mbytes - (cp & mmask);
59 			len -= n;
60 			while (n--)
61 				*d++ = *s++;
62 			n = len / mbytes;
63 			len &= mmask;
64 			while (n--) {
65 				*(mword *)d = *(const mword *)s;
66 				s += mbytes;
67 				d += mbytes;
68 			}
69 		}
70 		while (len--)
71 			*d++ = *s++;
72 	} else {
73 		/* copy backward */
74 		s += len;
75 		d += len;
76 		if ((((cp = (intptr_t)s) | (intptr_t)d) & mmask) &&
77 		    (((cp ^ (intptr_t)d) & mmask) == 0) && len >= mbytes) {
78 			/* low bits match: first align then copy entire words */
79 			n = cp & mmask;
80 			len -= n;
81 			while (n--)
82 				*--d = *--s;
83 			n = len / mbytes;
84 			len &= mmask;
85 			while (n--) {
86 				s -= mbytes;
87 				d -= mbytes;
88 				*(mword *)d = *(const mword *)s;
89 			}
90 		}
91 		while (len--)
92 			*--d = *--s;
93 	}
94  done:
95 #ifdef MEMMOVE
96 	return (dst);
97 #else
98 	return;
99 #endif
100 }
101