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