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