1982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer/* 2982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer * This file is subject to the terms and conditions of the GNU General Public 3982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer * License. See the file COPYING in the main directory of this archive 4982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer * for more details. 5982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer */ 6982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer 7982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer#include <linux/module.h> 8982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer#include <linux/string.h> 9982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer 10982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerervoid *memmove(void *dest, const void *src, size_t n) 11982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer{ 12982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer void *xdest = dest; 13982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer size_t temp; 14982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer 15982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if (!n) 16982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer return xdest; 17982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer 18982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if (dest < src) { 19982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if ((long)dest & 1) { 20982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer char *cdest = dest; 21982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer const char *csrc = src; 22982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer *cdest++ = *csrc++; 23982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer dest = cdest; 24982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer src = csrc; 25982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer n--; 26982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } 27982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if (n > 2 && (long)dest & 2) { 28982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer short *sdest = dest; 29982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer const short *ssrc = src; 30982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer *sdest++ = *ssrc++; 31982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer dest = sdest; 32982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer src = ssrc; 33982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer n -= 2; 34982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } 35982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer temp = n >> 2; 36982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if (temp) { 37982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer long *ldest = dest; 38982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer const long *lsrc = src; 39982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer temp--; 40982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer do 41982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer *ldest++ = *lsrc++; 42982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer while (temp--); 43982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer dest = ldest; 44982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer src = lsrc; 45982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } 46982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if (n & 2) { 47982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer short *sdest = dest; 48982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer const short *ssrc = src; 49982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer *sdest++ = *ssrc++; 50982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer dest = sdest; 51982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer src = ssrc; 52982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } 53982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if (n & 1) { 54982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer char *cdest = dest; 55982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer const char *csrc = src; 56982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer *cdest = *csrc; 57982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } 58982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } else { 59982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer dest = (char *)dest + n; 60982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer src = (const char *)src + n; 61982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if ((long)dest & 1) { 62982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer char *cdest = dest; 63982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer const char *csrc = src; 64982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer *--cdest = *--csrc; 65982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer dest = cdest; 66982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer src = csrc; 67982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer n--; 68982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } 69982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if (n > 2 && (long)dest & 2) { 70982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer short *sdest = dest; 71982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer const short *ssrc = src; 72982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer *--sdest = *--ssrc; 73982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer dest = sdest; 74982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer src = ssrc; 75982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer n -= 2; 76982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } 77982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer temp = n >> 2; 78982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if (temp) { 79982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer long *ldest = dest; 80982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer const long *lsrc = src; 81982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer temp--; 82982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer do 83982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer *--ldest = *--lsrc; 84982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer while (temp--); 85982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer dest = ldest; 86982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer src = lsrc; 87982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } 88982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if (n & 2) { 89982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer short *sdest = dest; 90982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer const short *ssrc = src; 91982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer *--sdest = *--ssrc; 92982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer dest = sdest; 93982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer src = ssrc; 94982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } 95982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer if (n & 1) { 96982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer char *cdest = dest; 97982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer const char *csrc = src; 98982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer *--cdest = *--csrc; 99982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } 100982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer } 101982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer return xdest; 102982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg Ungerer} 103982cd252ca0b63c11fe398c09c6f2b41217c78c0Greg UngererEXPORT_SYMBOL(memmove); 104