1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file COPYING in the main directory of this archive 4 * for more details. 5 */ 6 7 #include <linux/module.h> 8 #include <linux/string.h> 9 10 void *memmove(void *dest, const void *src, size_t n) 11 { 12 void *xdest = dest; 13 size_t temp; 14 15 if (!n) 16 return xdest; 17 18 if (dest < src) { 19 if ((long)dest & 1) { 20 char *cdest = dest; 21 const char *csrc = src; 22 *cdest++ = *csrc++; 23 dest = cdest; 24 src = csrc; 25 n--; 26 } 27 if (n > 2 && (long)dest & 2) { 28 short *sdest = dest; 29 const short *ssrc = src; 30 *sdest++ = *ssrc++; 31 dest = sdest; 32 src = ssrc; 33 n -= 2; 34 } 35 temp = n >> 2; 36 if (temp) { 37 long *ldest = dest; 38 const long *lsrc = src; 39 temp--; 40 do 41 *ldest++ = *lsrc++; 42 while (temp--); 43 dest = ldest; 44 src = lsrc; 45 } 46 if (n & 2) { 47 short *sdest = dest; 48 const short *ssrc = src; 49 *sdest++ = *ssrc++; 50 dest = sdest; 51 src = ssrc; 52 } 53 if (n & 1) { 54 char *cdest = dest; 55 const char *csrc = src; 56 *cdest = *csrc; 57 } 58 } else { 59 dest = (char *)dest + n; 60 src = (const char *)src + n; 61 if ((long)dest & 1) { 62 char *cdest = dest; 63 const char *csrc = src; 64 *--cdest = *--csrc; 65 dest = cdest; 66 src = csrc; 67 n--; 68 } 69 if (n > 2 && (long)dest & 2) { 70 short *sdest = dest; 71 const short *ssrc = src; 72 *--sdest = *--ssrc; 73 dest = sdest; 74 src = ssrc; 75 n -= 2; 76 } 77 temp = n >> 2; 78 if (temp) { 79 long *ldest = dest; 80 const long *lsrc = src; 81 temp--; 82 do 83 *--ldest = *--lsrc; 84 while (temp--); 85 dest = ldest; 86 src = lsrc; 87 } 88 if (n & 2) { 89 short *sdest = dest; 90 const short *ssrc = src; 91 *--sdest = *--ssrc; 92 dest = sdest; 93 src = ssrc; 94 } 95 if (n & 1) { 96 char *cdest = dest; 97 const char *csrc = src; 98 *--cdest = *--csrc; 99 } 100 } 101 return xdest; 102 } 103 EXPORT_SYMBOL(memmove); 104