1281494Sandrew/*- 2281494Sandrew * Copyright (c) 1990 The Regents of the University of California. 3281494Sandrew * All rights reserved. 4281494Sandrew * 5281494Sandrew * This code is derived from software contributed to Berkeley by 6281494Sandrew * Chris Torek. 7281494Sandrew * 8281494Sandrew * Redistribution and use in source and binary forms, with or without 9281494Sandrew * modification, are permitted provided that the following conditions 10281494Sandrew * are met: 11281494Sandrew * 1. Redistributions of source code must retain the above copyright 12281494Sandrew * notice, this list of conditions and the following disclaimer. 13281494Sandrew * 2. Redistributions in binary form must reproduce the above copyright 14281494Sandrew * notice, this list of conditions and the following disclaimer in the 15281494Sandrew * documentation and/or other materials provided with the distribution. 16281494Sandrew * 3. Neither the name of the University nor the names of its contributors 17281494Sandrew * may be used to endorse or promote products derived from this software 18281494Sandrew * without specific prior written permission. 19281494Sandrew * 20281494Sandrew * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21281494Sandrew * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22281494Sandrew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23281494Sandrew * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24281494Sandrew * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25281494Sandrew * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26281494Sandrew * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27281494Sandrew * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28281494Sandrew * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29281494Sandrew * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30281494Sandrew * SUCH DAMAGE. 31281494Sandrew * 32281494Sandrew * From: sys/powerpc/powerpc/bcopy.c 33281494Sandrew */ 34281494Sandrew 35281494Sandrew#include <sys/cdefs.h> 36281494Sandrew__FBSDID("$FreeBSD$"); 37281494Sandrew 38281494Sandrew#include <sys/param.h> 39281494Sandrew#include <sys/systm.h> 40281494Sandrew 41281494Sandrew/* 42281494Sandrew * sizeof(word) MUST BE A POWER OF TWO 43281494Sandrew * SO THAT wmask BELOW IS ALL ONES 44281494Sandrew */ 45281494Sandrewtypedef long word; /* "word" used for optimal copy speed */ 46281494Sandrew 47281494Sandrew#define wsize sizeof(word) 48281494Sandrew#define wmask (wsize - 1) 49281494Sandrew 50281494Sandrew/* 51281494Sandrew * Copy a block of memory, handling overlap. 52281494Sandrew * This is the routine that actually implements 53281494Sandrew * (the portable versions of) bcopy, memcpy, and memmove. 54281494Sandrew */ 55281494Sandrewvoid * 56281494Sandrewmemcpy(void *dst0, const void *src0, size_t length) 57281494Sandrew{ 58281494Sandrew char *dst; 59281494Sandrew const char *src; 60281494Sandrew size_t t; 61281494Sandrew 62281494Sandrew dst = dst0; 63281494Sandrew src = src0; 64281494Sandrew 65281494Sandrew if (length == 0 || dst == src) { /* nothing to do */ 66281494Sandrew goto done; 67281494Sandrew } 68281494Sandrew 69281494Sandrew /* 70281494Sandrew * Macros: loop-t-times; and loop-t-times, t>0 71281494Sandrew */ 72281494Sandrew#define TLOOP(s) if (t) TLOOP1(s) 73281494Sandrew#define TLOOP1(s) do { s; } while (--t) 74281494Sandrew 75281494Sandrew if ((unsigned long)dst < (unsigned long)src) { 76281494Sandrew /* 77281494Sandrew * Copy forward. 78281494Sandrew */ 79281494Sandrew t = (size_t)src; /* only need low bits */ 80281494Sandrew 81281494Sandrew if ((t | (uintptr_t)dst) & wmask) { 82281494Sandrew /* 83281494Sandrew * Try to align operands. This cannot be done 84281494Sandrew * unless the low bits match. 85281494Sandrew */ 86281494Sandrew if ((t ^ (uintptr_t)dst) & wmask || length < wsize) { 87281494Sandrew t = length; 88281494Sandrew } else { 89281494Sandrew t = wsize - (t & wmask); 90281494Sandrew } 91281494Sandrew 92281494Sandrew length -= t; 93281494Sandrew TLOOP1(*dst++ = *src++); 94281494Sandrew } 95281494Sandrew /* 96281494Sandrew * Copy whole words, then mop up any trailing bytes. 97281494Sandrew */ 98281494Sandrew t = length / wsize; 99281494Sandrew TLOOP(*(word *)dst = *(const word *)src; src += wsize; 100281494Sandrew dst += wsize); 101281494Sandrew t = length & wmask; 102281494Sandrew TLOOP(*dst++ = *src++); 103281494Sandrew } else { 104281494Sandrew /* 105281494Sandrew * Copy backwards. Otherwise essentially the same. 106281494Sandrew * Alignment works as before, except that it takes 107281494Sandrew * (t&wmask) bytes to align, not wsize-(t&wmask). 108281494Sandrew */ 109281494Sandrew src += length; 110281494Sandrew dst += length; 111281494Sandrew t = (uintptr_t)src; 112281494Sandrew 113281494Sandrew if ((t | (uintptr_t)dst) & wmask) { 114281494Sandrew if ((t ^ (uintptr_t)dst) & wmask || length <= wsize) { 115281494Sandrew t = length; 116281494Sandrew } else { 117281494Sandrew t &= wmask; 118281494Sandrew } 119281494Sandrew 120281494Sandrew length -= t; 121281494Sandrew TLOOP1(*--dst = *--src); 122281494Sandrew } 123281494Sandrew t = length / wsize; 124281494Sandrew TLOOP(src -= wsize; dst -= wsize; 125281494Sandrew *(word *)dst = *(const word *)src); 126281494Sandrew t = length & wmask; 127281494Sandrew TLOOP(*--dst = *--src); 128281494Sandrew } 129281494Sandrewdone: 130281494Sandrew return (dst0); 131281494Sandrew} 132281494Sandrew 133281494Sandrewvoid 134281494Sandrewbcopy(const void *src0, void *dst0, size_t length) 135281494Sandrew{ 136281494Sandrew 137281494Sandrew memcpy(dst0, src0, length); 138281494Sandrew} 139281494Sandrew 140