1 /*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * %sccs.include.redist.c%
9 */
10
11 #if defined(LIBC_SCCS) && !defined(lint)
12 static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 06/04/93";
13 #endif /* LIBC_SCCS and not lint */
14
15 #include <sys/cdefs.h>
16 #include <string.h>
17
18 /*
19 * sizeof(word) MUST BE A POWER OF TWO
20 * SO THAT wmask BELOW IS ALL ONES
21 */
22 typedef int word; /* "word" used for optimal copy speed */
23
24 #define wsize sizeof(word)
25 #define wmask (wsize - 1)
26
27 /*
28 * Copy a block of memory, handling overlap.
29 * This is the routine that actually implements
30 * (the portable versions of) bcopy, memcpy, and memmove.
31 */
32 #ifdef MEMCOPY
33 void *
memcpy(dst0,src0,length)34 memcpy(dst0, src0, length)
35 #else
36 #ifdef MEMMOVE
37 void *
38 memmove(dst0, src0, length)
39 #else
40 void
41 bcopy(src0, dst0, length)
42 #endif
43 #endif
44 void *dst0;
45 const void *src0;
46 register size_t length;
47 {
48 register char *dst = dst0;
49 register const char *src = src0;
50 register size_t t;
51
52 if (length == 0 || dst == src) /* nothing to do */
53 goto done;
54
55 /*
56 * Macros: loop-t-times; and loop-t-times, t>0
57 */
58 #define TLOOP(s) if (t) TLOOP1(s)
59 #define TLOOP1(s) do { s; } while (--t)
60
61 if ((unsigned long)dst < (unsigned long)src) {
62 /*
63 * Copy forward.
64 */
65 t = (int)src; /* only need low bits */
66 if ((t | (int)dst) & wmask) {
67 /*
68 * Try to align operands. This cannot be done
69 * unless the low bits match.
70 */
71 if ((t ^ (int)dst) & wmask || length < wsize)
72 t = length;
73 else
74 t = wsize - (t & wmask);
75 length -= t;
76 TLOOP1(*dst++ = *src++);
77 }
78 /*
79 * Copy whole words, then mop up any trailing bytes.
80 */
81 t = length / wsize;
82 TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
83 t = length & wmask;
84 TLOOP(*dst++ = *src++);
85 } else {
86 /*
87 * Copy backwards. Otherwise essentially the same.
88 * Alignment works as before, except that it takes
89 * (t&wmask) bytes to align, not wsize-(t&wmask).
90 */
91 src += length;
92 dst += length;
93 t = (int)src;
94 if ((t | (int)dst) & wmask) {
95 if ((t ^ (int)dst) & wmask || length <= wsize)
96 t = length;
97 else
98 t &= wmask;
99 length -= t;
100 TLOOP1(*--dst = *--src);
101 }
102 t = length / wsize;
103 TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
104 t = length & wmask;
105 TLOOP(*--dst = *--src);
106 }
107 done:
108 #if defined(MEMCOPY) || defined(MEMMOVE)
109 return (dst0);
110 #else
111 return;
112 #endif
113 }
114