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.8 (Berkeley) 06/23/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 #ifdef MEMCOPY 33 void * 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 char *dst0; 45 const char *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 return; 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 #ifdef MEMCOPY 108 return(dst0); 109 #else 110 #ifdef MEMMOVE 111 return(dst0); 112 #else 113 return; 114 #endif 115 #endif 116 } 117