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 13 #ifdef __HAVE_ARCH_MEMMOVE 14 void *memmove(void *d, const void *s, size_t count) 15 { 16 unsigned long dst, src; 17 18 if (!count) 19 return d; 20 21 if (d < s) { 22 dst = (unsigned long) d; 23 src = (unsigned long) s; 24 25 if ((count < 8) || ((dst ^ src) & 3)) 26 goto restup; 27 28 if (dst & 1) { 29 *(char *)dst++ = *(char *)src++; 30 count--; 31 } 32 if (dst & 2) { 33 *(short *)dst = *(short *)src; 34 src += 2; 35 dst += 2; 36 count -= 2; 37 } 38 while (count > 3) { 39 *(long *)dst = *(long *)src; 40 src += 4; 41 dst += 4; 42 count -= 4; 43 } 44 restup: 45 while (count--) 46 *(char *)dst++ = *(char *)src++; 47 } else { 48 dst = (unsigned long) d + count; 49 src = (unsigned long) s + count; 50 51 if ((count < 8) || ((dst ^ src) & 3)) 52 goto restdown; 53 54 if (dst & 1) { 55 src--; 56 dst--; 57 count--; 58 *(char *)dst = *(char *)src; 59 } 60 if (dst & 2) { 61 src -= 2; 62 dst -= 2; 63 count -= 2; 64 *(short *)dst = *(short *)src; 65 } 66 while (count > 3) { 67 src -= 4; 68 dst -= 4; 69 count -= 4; 70 *(long *)dst = *(long *)src; 71 } 72 restdown: 73 while (count--) { 74 src--; 75 dst--; 76 *(char *)dst = *(char *)src; 77 } 78 } 79 80 return d; 81 } 82 #endif /* __HAVE_ARCH_MEMMOVE */ 83