|
|
1.1 root 1: /*-
2: * Copyright (c) 1990 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Chris Torek.
7: *
8: * Redistribution and use in source and binary forms are permitted provided
9: * that: (1) source distributions retain this entire copyright notice and
10: * comment, and (2) distributions including binaries display the following
11: * acknowledgement: ``This product includes software developed by the
12: * University of California, Berkeley and its contributors'' in the
13: * documentation or other materials provided with the distribution and in
14: * all advertising materials mentioning features or use of this software.
15: * Neither the name of the University nor the names of its contributors may
16: * be used to endorse or promote products derived from this software without
17: * specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #if defined(LIBC_SCCS) && !defined(lint)
24: static char sccsid[] = "@(#)bcopy.c 5.8 (Berkeley) 6/23/90";
25: #endif /* LIBC_SCCS and not lint */
26:
27: #include <sys/stdc.h>
28: #include <string.h>
29:
30: /*
31: * sizeof(word) MUST BE A POWER OF TWO
32: * SO THAT wmask BELOW IS ALL ONES
33: */
34: typedef int word; /* "word" used for optimal copy speed */
35:
36: #define wsize sizeof(word)
37: #define wmask (wsize - 1)
38:
39: /*
40: * Copy a block of memory, handling overlap.
41: * This is the routine that actually implements
42: * (the portable versions of) bcopy, memcpy, and memmove.
43: */
44: #ifdef MEMCOPY
45: void *
46: memcpy(dst0, src0, length)
47: #else
48: #ifdef MEMMOVE
49: void *
50: memmove(dst0, src0, length)
51: #else
52: void
53: bcopy(src0, dst0, length)
54: #endif
55: #endif
56: char *dst0;
57: const char *src0;
58: register size_t length;
59: {
60: register char *dst = dst0;
61: register const char *src = src0;
62: register size_t t;
63:
64: if (length == 0 || dst == src) /* nothing to do */
65: return;
66:
67: /*
68: * Macros: loop-t-times; and loop-t-times, t>0
69: */
70: #define TLOOP(s) if (t) TLOOP1(s)
71: #define TLOOP1(s) do { s; } while (--t)
72:
73: if ((unsigned long)dst < (unsigned long)src) {
74: /*
75: * Copy forward.
76: */
77: t = (int)src; /* only need low bits */
78: if ((t | (int)dst) & wmask) {
79: /*
80: * Try to align operands. This cannot be done
81: * unless the low bits match.
82: */
83: if ((t ^ (int)dst) & wmask || length < wsize)
84: t = length;
85: else
86: t = wsize - (t & wmask);
87: length -= t;
88: TLOOP1(*dst++ = *src++);
89: }
90: /*
91: * Copy whole words, then mop up any trailing bytes.
92: */
93: t = length / wsize;
94: TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
95: t = length & wmask;
96: TLOOP(*dst++ = *src++);
97: } else {
98: /*
99: * Copy backwards. Otherwise essentially the same.
100: * Alignment works as before, except that it takes
101: * (t&wmask) bytes to align, not wsize-(t&wmask).
102: */
103: src += length;
104: dst += length;
105: t = (int)src;
106: if ((t | (int)dst) & wmask) {
107: if ((t ^ (int)dst) & wmask || length <= wsize)
108: t = length;
109: else
110: t &= wmask;
111: length -= t;
112: TLOOP1(*--dst = *--src);
113: }
114: t = length / wsize;
115: TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
116: t = length & wmask;
117: TLOOP(*--dst = *--src);
118: }
119: #ifdef MEMCOPY
120: return(dst0);
121: #else
122: #ifdef MEMMOVE
123: return(dst0);
124: #else
125: return;
126: #endif
127: #endif
128: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.