xref: /titanic_52/usr/src/boot/lib/libc/string/bcopy.c (revision 4a5d661a82b942b6538acd26209d959ce98b593a)
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
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