142145Sbostic /*- 242145Sbostic * Copyright (c) 1990 The Regents of the University of California. 335110Sbostic * All rights reserved. 435110Sbostic * 542145Sbostic * This code is derived from software contributed to Berkeley by 642145Sbostic * Chris Torek. 742145Sbostic * 842145Sbostic * %sccs.include.redist.c% 930423Smckusick */ 1030423Smckusick 1130423Smckusick #if defined(LIBC_SCCS) && !defined(lint) 12*43487Sbostic static char sccsid[] = "@(#)bcopy.c 5.8 (Berkeley) 06/23/90"; 1335110Sbostic #endif /* LIBC_SCCS and not lint */ 1430423Smckusick 1542145Sbostic #include <sys/stdc.h> 1642145Sbostic #include <string.h> 1737105Sbostic 1830423Smckusick /* 1942145Sbostic * sizeof(word) MUST BE A POWER OF TWO 2042145Sbostic * SO THAT wmask BELOW IS ALL ONES 2130423Smckusick */ 2242145Sbostic typedef int word; /* "word" used for optimal copy speed */ 2338485Skarels 2442145Sbostic #define wsize sizeof(word) 2542145Sbostic #define wmask (wsize - 1) 2638485Skarels 2742145Sbostic /* 2842145Sbostic * Copy a block of memory, handling overlap. 2942145Sbostic * This is the routine that actually implements 3042145Sbostic * (the portable versions of) bcopy, memcpy, and memmove. 3142145Sbostic */ 32*43487Sbostic #ifdef MEMCOPY 33*43487Sbostic void * 34*43487Sbostic memcpy(dst0, src0, length) 35*43487Sbostic #else 36*43487Sbostic #ifdef MEMMOVE 37*43487Sbostic void * 38*43487Sbostic memmove(dst0, src0, length) 39*43487Sbostic #else 4042145Sbostic void 4142145Sbostic bcopy(src0, dst0, length) 42*43487Sbostic #endif 43*43487Sbostic #endif 4442145Sbostic char *dst0; 4542145Sbostic const char *src0; 4642145Sbostic register size_t length; 4730423Smckusick { 4842145Sbostic register char *dst = dst0; 4942145Sbostic register const char *src = src0; 5042145Sbostic register size_t t; 5142145Sbostic 5242145Sbostic if (length == 0 || dst == src) /* nothing to do */ 5342145Sbostic return; 5442145Sbostic 5542145Sbostic /* 5642145Sbostic * Macros: loop-t-times; and loop-t-times, t>0 5742145Sbostic */ 5842145Sbostic #define TLOOP(s) if (t) TLOOP1(s) 5942145Sbostic #define TLOOP1(s) do { s; } while (--t) 6042145Sbostic 6142145Sbostic if ((unsigned long)dst < (unsigned long)src) { 6242145Sbostic /* 6342145Sbostic * Copy forward. 6442145Sbostic */ 6542145Sbostic t = (int)src; /* only need low bits */ 6642145Sbostic if ((t | (int)dst) & wmask) { 6742145Sbostic /* 6842145Sbostic * Try to align operands. This cannot be done 6942145Sbostic * unless the low bits match. 7042145Sbostic */ 7142145Sbostic if ((t ^ (int)dst) & wmask || length < wsize) 7242145Sbostic t = length; 7342145Sbostic else 7442145Sbostic t = wsize - (t & wmask); 7542145Sbostic length -= t; 7642145Sbostic TLOOP1(*dst++ = *src++); 7730423Smckusick } 7842145Sbostic /* 7942145Sbostic * Copy whole words, then mop up any trailing bytes. 8042145Sbostic */ 8142145Sbostic t = length / wsize; 8242145Sbostic TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); 8342145Sbostic t = length & wmask; 8442145Sbostic TLOOP(*dst++ = *src++); 8542145Sbostic } else { 8642145Sbostic /* 8742145Sbostic * Copy backwards. Otherwise essentially the same. 8842145Sbostic * Alignment works as before, except that it takes 8942145Sbostic * (t&wmask) bytes to align, not wsize-(t&wmask). 9042145Sbostic */ 9142145Sbostic src += length; 9242145Sbostic dst += length; 9342145Sbostic t = (int)src; 9442145Sbostic if ((t | (int)dst) & wmask) { 9542145Sbostic if ((t ^ (int)dst) & wmask || length <= wsize) 9642145Sbostic t = length; 9742145Sbostic else 9842145Sbostic t &= wmask; 9942145Sbostic length -= t; 10042145Sbostic TLOOP1(*--dst = *--src); 10142145Sbostic } 10242145Sbostic t = length / wsize; 10342145Sbostic TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); 10442145Sbostic t = length & wmask; 10542145Sbostic TLOOP(*--dst = *--src); 10642145Sbostic } 107*43487Sbostic #ifdef MEMCOPY 108*43487Sbostic return(dst0); 109*43487Sbostic #else 110*43487Sbostic #ifdef MEMMOVE 111*43487Sbostic return(dst0); 112*43487Sbostic #else 11342145Sbostic return; 114*43487Sbostic #endif 115*43487Sbostic #endif 11630423Smckusick } 117