1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- /*
- * 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;
- }
|