| /* | |
| * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> | |
| * Copyright (C) 2004 Microtronix Datacom Ltd | |
| * | |
| * This file is subject to the terms and conditions of the GNU General Public | |
| * License. See the file "COPYING" in the main directory of this archive | |
| * for more details. | |
| */ | |
| #include <linux/types.h> | |
| #include <linux/string.h> | |
| void *memmove(void *d, const void *s, size_t count) | |
| { | |
| unsigned long dst, src; | |
| if (!count) | |
| return d; | |
| if (d < s) { | |
| dst = (unsigned long) d; | |
| src = (unsigned long) s; | |
| if ((count < 8) || ((dst ^ src) & 3)) | |
| goto restup; | |
| if (dst & 1) { | |
| *(char *)dst++ = *(char *)src++; | |
| count--; | |
| } | |
| if (dst & 2) { | |
| *(short *)dst = *(short *)src; | |
| src += 2; | |
| dst += 2; | |
| count -= 2; | |
| } | |
| while (count > 3) { | |
| *(long *)dst = *(long *)src; | |
| src += 4; | |
| dst += 4; | |
| count -= 4; | |
| } | |
| restup: | |
| while (count--) | |
| *(char *)dst++ = *(char *)src++; | |
| } else { | |
| dst = (unsigned long) d + count; | |
| src = (unsigned long) s + count; | |
| if ((count < 8) || ((dst ^ src) & 3)) | |
| goto restdown; | |
| if (dst & 1) { | |
| src--; | |
| dst--; | |
| count--; | |
| *(char *)dst = *(char *)src; | |
| } | |
| if (dst & 2) { | |
| src -= 2; | |
| dst -= 2; | |
| count -= 2; | |
| *(short *)dst = *(short *)src; | |
| } | |
| while (count > 3) { | |
| src -= 4; | |
| dst -= 4; | |
| count -= 4; | |
| *(long *)dst = *(long *)src; | |
| } | |
| restdown: | |
| while (count--) { | |
| src--; | |
| dst--; | |
| *(char *)dst = *(char *)src; | |
| } | |
| } | |
| return d; | |
| } |