177957Sbenno/*- 277957Sbenno * Copyright (c) 1990 The Regents of the University of California. 377957Sbenno * All rights reserved. 477957Sbenno * 577957Sbenno * This code is derived from software contributed to Berkeley by 677957Sbenno * Chris Torek. 777957Sbenno * 877957Sbenno * Redistribution and use in source and binary forms, with or without 977957Sbenno * modification, are permitted provided that the following conditions 1077957Sbenno * are met: 1177957Sbenno * 1. Redistributions of source code must retain the above copyright 1277957Sbenno * notice, this list of conditions and the following disclaimer. 1377957Sbenno * 2. Redistributions in binary form must reproduce the above copyright 1477957Sbenno * notice, this list of conditions and the following disclaimer in the 1577957Sbenno * documentation and/or other materials provided with the distribution. 1677957Sbenno * 4. Neither the name of the University nor the names of its contributors 1777957Sbenno * may be used to endorse or promote products derived from this software 1877957Sbenno * without specific prior written permission. 1977957Sbenno * 2077957Sbenno * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2177957Sbenno * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2277957Sbenno * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2377957Sbenno * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2477957Sbenno * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2577957Sbenno * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2677957Sbenno * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2777957Sbenno * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2877957Sbenno * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2977957Sbenno * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3077957Sbenno * SUCH DAMAGE. 3177957Sbenno */ 3277957Sbenno 3377957Sbenno#if defined(LIBC_SCCS) && !defined(lint) 3477957Sbenno#if 0 3577957Sbennostatic char *sccsid = "from: @(#)bcopy.c 5.11 (Berkeley) 6/21/91"; 3677957Sbenno#endif 3777957Sbenno#if 0 3877957Sbennostatic char *rcsid = "$NetBSD: bcopy.c,v 1.2 1997/04/16 22:09:41 thorpej Exp $"; 3977957Sbenno#endif 4077957Sbenno#endif /* LIBC_SCCS and not lint */ 41113038Sobrien#include <sys/cdefs.h> 42113038Sobrien__FBSDID("$FreeBSD$"); 4377957Sbenno 4477957Sbenno#include <sys/param.h> 4577957Sbenno#ifdef _KERNEL 4677957Sbenno#include <sys/systm.h> 4777957Sbenno#else 4877957Sbenno#include <string.h> 4977957Sbenno#endif 5077957Sbenno 5177957Sbenno/* 5277957Sbenno * sizeof(word) MUST BE A POWER OF TWO 5377957Sbenno * SO THAT wmask BELOW IS ALL ONES 5477957Sbenno */ 55209850Snwhitehorntypedef long word; /* "word" used for optimal copy speed */ 5677957Sbenno 5777957Sbenno#define wsize sizeof(word) 5877957Sbenno#define wmask (wsize - 1) 5977957Sbenno 6077957Sbenno/* 6177957Sbenno * Copy a block of memory, handling overlap. 6277957Sbenno * This is the routine that actually implements 6377957Sbenno * (the portable versions of) bcopy, memcpy, and memmove. 6477957Sbenno */ 6577957Sbennovoid * 6677957Sbennomemcpy(void *dst0, const void *src0, size_t length) 6777957Sbenno{ 6877957Sbenno char *dst; 6977957Sbenno const char *src; 7077957Sbenno size_t t; 7177957Sbenno 7277957Sbenno dst = dst0; 7377957Sbenno src = src0; 7477957Sbenno 7577957Sbenno if (length == 0 || dst == src) { /* nothing to do */ 7677957Sbenno goto done; 7777957Sbenno } 7877957Sbenno 7977957Sbenno /* 8077957Sbenno * Macros: loop-t-times; and loop-t-times, t>0 8177957Sbenno */ 8277957Sbenno#define TLOOP(s) if (t) TLOOP1(s) 8377957Sbenno#define TLOOP1(s) do { s; } while (--t) 8477957Sbenno 8577957Sbenno if ((unsigned long)dst < (unsigned long)src) { 8677957Sbenno /* 8777957Sbenno * Copy forward. 8877957Sbenno */ 89209850Snwhitehorn t = (size_t)src; /* only need low bits */ 9077957Sbenno 91209850Snwhitehorn if ((t | (uintptr_t)dst) & wmask) { 9277957Sbenno /* 9377957Sbenno * Try to align operands. This cannot be done 9477957Sbenno * unless the low bits match. 9577957Sbenno */ 96209850Snwhitehorn if ((t ^ (uintptr_t)dst) & wmask || length < wsize) { 9777957Sbenno t = length; 9877957Sbenno } else { 9977957Sbenno t = wsize - (t & wmask); 10077957Sbenno } 10177957Sbenno 10277957Sbenno length -= t; 10377957Sbenno TLOOP1(*dst++ = *src++); 10477957Sbenno } 10577957Sbenno /* 10677957Sbenno * Copy whole words, then mop up any trailing bytes. 10777957Sbenno */ 10877957Sbenno t = length / wsize; 10977957Sbenno TLOOP(*(word *)dst = *(const word *)src; src += wsize; 11077957Sbenno dst += wsize); 11177957Sbenno t = length & wmask; 11277957Sbenno TLOOP(*dst++ = *src++); 11377957Sbenno } else { 11477957Sbenno /* 11577957Sbenno * Copy backwards. Otherwise essentially the same. 11677957Sbenno * Alignment works as before, except that it takes 11777957Sbenno * (t&wmask) bytes to align, not wsize-(t&wmask). 11877957Sbenno */ 11977957Sbenno src += length; 12077957Sbenno dst += length; 121209850Snwhitehorn t = (uintptr_t)src; 12277957Sbenno 123209850Snwhitehorn if ((t | (uintptr_t)dst) & wmask) { 124209850Snwhitehorn if ((t ^ (uintptr_t)dst) & wmask || length <= wsize) { 12577957Sbenno t = length; 12677957Sbenno } else { 12777957Sbenno t &= wmask; 12877957Sbenno } 12977957Sbenno 13077957Sbenno length -= t; 13177957Sbenno TLOOP1(*--dst = *--src); 13277957Sbenno } 13377957Sbenno t = length / wsize; 13477957Sbenno TLOOP(src -= wsize; dst -= wsize; 13577957Sbenno *(word *)dst = *(const word *)src); 13677957Sbenno t = length & wmask; 13777957Sbenno TLOOP(*--dst = *--src); 13877957Sbenno } 13977957Sbennodone: 14077957Sbenno return (dst0); 14177957Sbenno} 14277957Sbenno 14377957Sbennovoid 14477957Sbennobcopy(const void *src0, void *dst0, size_t length) 14577957Sbenno{ 14677957Sbenno 14777957Sbenno memcpy(dst0, src0, length); 14877957Sbenno} 14999035Sbenno 150