1*4a5d661aSToomas Soome /*-
2*4a5d661aSToomas Soome * Copyright (c) 1990, 1993
3*4a5d661aSToomas Soome * The Regents of the University of California. All rights reserved.
4*4a5d661aSToomas Soome *
5*4a5d661aSToomas Soome * This code is derived from software contributed to Berkeley by
6*4a5d661aSToomas Soome * Chris Torek.
7*4a5d661aSToomas Soome *
8*4a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without
9*4a5d661aSToomas Soome * modification, are permitted provided that the following conditions
10*4a5d661aSToomas Soome * are met:
11*4a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright
12*4a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer.
13*4a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
14*4a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the
15*4a5d661aSToomas Soome * documentation and/or other materials provided with the distribution.
16*4a5d661aSToomas Soome * 3. Neither the name of the University nor the names of its contributors
17*4a5d661aSToomas Soome * may be used to endorse or promote products derived from this software
18*4a5d661aSToomas Soome * without specific prior written permission.
19*4a5d661aSToomas Soome *
20*4a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21*4a5d661aSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22*4a5d661aSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23*4a5d661aSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24*4a5d661aSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25*4a5d661aSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26*4a5d661aSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*4a5d661aSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28*4a5d661aSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29*4a5d661aSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30*4a5d661aSToomas Soome * SUCH DAMAGE.
31*4a5d661aSToomas Soome */
32*4a5d661aSToomas Soome
33*4a5d661aSToomas Soome #if defined(LIBC_SCCS) && !defined(lint)
34*4a5d661aSToomas Soome static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
35*4a5d661aSToomas Soome #endif /* LIBC_SCCS and not lint */
36*4a5d661aSToomas Soome #include <sys/cdefs.h>
37*4a5d661aSToomas Soome __FBSDID("$FreeBSD$");
38*4a5d661aSToomas Soome
39*4a5d661aSToomas Soome #include <sys/types.h>
40*4a5d661aSToomas Soome
41*4a5d661aSToomas Soome /*
42*4a5d661aSToomas Soome * sizeof(word) MUST BE A POWER OF TWO
43*4a5d661aSToomas Soome * SO THAT wmask BELOW IS ALL ONES
44*4a5d661aSToomas Soome */
45*4a5d661aSToomas Soome typedef int word; /* "word" used for optimal copy speed */
46*4a5d661aSToomas Soome
47*4a5d661aSToomas Soome #define wsize sizeof(word)
48*4a5d661aSToomas Soome #define wmask (wsize - 1)
49*4a5d661aSToomas Soome
50*4a5d661aSToomas Soome /*
51*4a5d661aSToomas Soome * Copy a block of memory, handling overlap.
52*4a5d661aSToomas Soome * This is the routine that actually implements
53*4a5d661aSToomas Soome * (the portable versions of) bcopy, memcpy, and memmove.
54*4a5d661aSToomas Soome */
55*4a5d661aSToomas Soome #if defined(MEMCOPY) || defined(MEMMOVE)
56*4a5d661aSToomas Soome #include <string.h>
57*4a5d661aSToomas Soome
58*4a5d661aSToomas Soome void *
59*4a5d661aSToomas Soome #ifdef MEMCOPY
memcpy(void * dst0,const void * src0,size_t length)60*4a5d661aSToomas Soome memcpy
61*4a5d661aSToomas Soome #else
62*4a5d661aSToomas Soome memmove
63*4a5d661aSToomas Soome #endif
64*4a5d661aSToomas Soome (void *dst0, const void *src0, size_t length)
65*4a5d661aSToomas Soome #else
66*4a5d661aSToomas Soome #include <strings.h>
67*4a5d661aSToomas Soome
68*4a5d661aSToomas Soome void
69*4a5d661aSToomas Soome bcopy(const void *src0, void *dst0, size_t length)
70*4a5d661aSToomas Soome #endif
71*4a5d661aSToomas Soome {
72*4a5d661aSToomas Soome char *dst = dst0;
73*4a5d661aSToomas Soome const char *src = src0;
74*4a5d661aSToomas Soome size_t t;
75*4a5d661aSToomas Soome
76*4a5d661aSToomas Soome if (length == 0 || dst == src) /* nothing to do */
77*4a5d661aSToomas Soome goto done;
78*4a5d661aSToomas Soome
79*4a5d661aSToomas Soome /*
80*4a5d661aSToomas Soome * Macros: loop-t-times; and loop-t-times, t>0
81*4a5d661aSToomas Soome */
82*4a5d661aSToomas Soome #define TLOOP(s) if (t) TLOOP1(s)
83*4a5d661aSToomas Soome #define TLOOP1(s) do { s; } while (--t)
84*4a5d661aSToomas Soome
85*4a5d661aSToomas Soome if ((unsigned long)dst < (unsigned long)src) {
86*4a5d661aSToomas Soome /*
87*4a5d661aSToomas Soome * Copy forward.
88*4a5d661aSToomas Soome */
89*4a5d661aSToomas Soome t = (uintptr_t)src; /* only need low bits */
90*4a5d661aSToomas Soome if ((t | (uintptr_t)dst) & wmask) {
91*4a5d661aSToomas Soome /*
92*4a5d661aSToomas Soome * Try to align operands. This cannot be done
93*4a5d661aSToomas Soome * unless the low bits match.
94*4a5d661aSToomas Soome */
95*4a5d661aSToomas Soome if ((t ^ (uintptr_t)dst) & wmask || length < wsize)
96*4a5d661aSToomas Soome t = length;
97*4a5d661aSToomas Soome else
98*4a5d661aSToomas Soome t = wsize - (t & wmask);
99*4a5d661aSToomas Soome length -= t;
100*4a5d661aSToomas Soome TLOOP1(*dst++ = *src++);
101*4a5d661aSToomas Soome }
102*4a5d661aSToomas Soome /*
103*4a5d661aSToomas Soome * Copy whole words, then mop up any trailing bytes.
104*4a5d661aSToomas Soome */
105*4a5d661aSToomas Soome t = length / wsize;
106*4a5d661aSToomas Soome TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
107*4a5d661aSToomas Soome t = length & wmask;
108*4a5d661aSToomas Soome TLOOP(*dst++ = *src++);
109*4a5d661aSToomas Soome } else {
110*4a5d661aSToomas Soome /*
111*4a5d661aSToomas Soome * Copy backwards. Otherwise essentially the same.
112*4a5d661aSToomas Soome * Alignment works as before, except that it takes
113*4a5d661aSToomas Soome * (t&wmask) bytes to align, not wsize-(t&wmask).
114*4a5d661aSToomas Soome */
115*4a5d661aSToomas Soome src += length;
116*4a5d661aSToomas Soome dst += length;
117*4a5d661aSToomas Soome t = (uintptr_t)src;
118*4a5d661aSToomas Soome if ((t | (uintptr_t)dst) & wmask) {
119*4a5d661aSToomas Soome if ((t ^ (uintptr_t)dst) & wmask || length <= wsize)
120*4a5d661aSToomas Soome t = length;
121*4a5d661aSToomas Soome else
122*4a5d661aSToomas Soome t &= wmask;
123*4a5d661aSToomas Soome length -= t;
124*4a5d661aSToomas Soome TLOOP1(*--dst = *--src);
125*4a5d661aSToomas Soome }
126*4a5d661aSToomas Soome t = length / wsize;
127*4a5d661aSToomas Soome TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
128*4a5d661aSToomas Soome t = length & wmask;
129*4a5d661aSToomas Soome TLOOP(*--dst = *--src);
130*4a5d661aSToomas Soome }
131*4a5d661aSToomas Soome done:
132*4a5d661aSToomas Soome #if defined(MEMCOPY) || defined(MEMMOVE)
133*4a5d661aSToomas Soome return (dst0);
134*4a5d661aSToomas Soome #else
135*4a5d661aSToomas Soome return;
136*4a5d661aSToomas Soome #endif
137*4a5d661aSToomas Soome }
138