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 * %sccs.include.redist.c% 9 */ 10 11 #if defined(LIBC_SCCS) && !defined(lint) 12 static char sccsid[] = "@(#)bcopy.c 5.7 (Berkeley) 05/16/90"; 13 #endif /* LIBC_SCCS and not lint */ 14 15 #include <sys/stdc.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 void 33 bcopy(src0, dst0, length) 34 char *dst0; 35 const char *src0; 36 register size_t length; 37 { 38 register char *dst = dst0; 39 register const char *src = src0; 40 register size_t t; 41 42 if (length == 0 || dst == src) /* nothing to do */ 43 return; 44 45 /* 46 * Macros: loop-t-times; and loop-t-times, t>0 47 */ 48 #define TLOOP(s) if (t) TLOOP1(s) 49 #define TLOOP1(s) do { s; } while (--t) 50 51 if ((unsigned long)dst < (unsigned long)src) { 52 /* 53 * Copy forward. 54 */ 55 t = (int)src; /* only need low bits */ 56 if ((t | (int)dst) & wmask) { 57 /* 58 * Try to align operands. This cannot be done 59 * unless the low bits match. 60 */ 61 if ((t ^ (int)dst) & wmask || length < wsize) 62 t = length; 63 else 64 t = wsize - (t & wmask); 65 length -= t; 66 TLOOP1(*dst++ = *src++); 67 } 68 /* 69 * Copy whole words, then mop up any trailing bytes. 70 */ 71 t = length / wsize; 72 TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); 73 t = length & wmask; 74 TLOOP(*dst++ = *src++); 75 } else { 76 /* 77 * Copy backwards. Otherwise essentially the same. 78 * Alignment works as before, except that it takes 79 * (t&wmask) bytes to align, not wsize-(t&wmask). 80 */ 81 src += length; 82 dst += length; 83 t = (int)src; 84 if ((t | (int)dst) & wmask) { 85 if ((t ^ (int)dst) & wmask || length <= wsize) 86 t = length; 87 else 88 t &= wmask; 89 length -= t; 90 TLOOP1(*--dst = *--src); 91 } 92 t = length / wsize; 93 TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); 94 t = length & wmask; 95 TLOOP(*--dst = *--src); 96 } 97 return; 98 } 99