memmove.c (1422B)
1/* 2 * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> 3 * Copyright (C) 2004 Microtronix Datacom Ltd 4 * 5 * This file is subject to the terms and conditions of the GNU General Public 6 * License. See the file "COPYING" in the main directory of this archive 7 * for more details. 8 */ 9 10#include <linux/types.h> 11#include <linux/string.h> 12 13void *memmove(void *d, const void *s, size_t count) 14{ 15 unsigned long dst, src; 16 17 if (!count) 18 return d; 19 20 if (d < s) { 21 dst = (unsigned long) d; 22 src = (unsigned long) s; 23 24 if ((count < 8) || ((dst ^ src) & 3)) 25 goto restup; 26 27 if (dst & 1) { 28 *(char *)dst++ = *(char *)src++; 29 count--; 30 } 31 if (dst & 2) { 32 *(short *)dst = *(short *)src; 33 src += 2; 34 dst += 2; 35 count -= 2; 36 } 37 while (count > 3) { 38 *(long *)dst = *(long *)src; 39 src += 4; 40 dst += 4; 41 count -= 4; 42 } 43restup: 44 while (count--) 45 *(char *)dst++ = *(char *)src++; 46 } else { 47 dst = (unsigned long) d + count; 48 src = (unsigned long) s + count; 49 50 if ((count < 8) || ((dst ^ src) & 3)) 51 goto restdown; 52 53 if (dst & 1) { 54 src--; 55 dst--; 56 count--; 57 *(char *)dst = *(char *)src; 58 } 59 if (dst & 2) { 60 src -= 2; 61 dst -= 2; 62 count -= 2; 63 *(short *)dst = *(short *)src; 64 } 65 while (count > 3) { 66 src -= 4; 67 dst -= 4; 68 count -= 4; 69 *(long *)dst = *(long *)src; 70 } 71restdown: 72 while (count--) { 73 src--; 74 dst--; 75 *(char *)dst = *(char *)src; 76 } 77 } 78 79 return d; 80}