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 *memcpy(void *to, const void *from, size_t n) 11 { 12 void *xto = to; 13 size_t temp; 14 15 if (!n) 16 return xto; 17 if ((long)to & 1) { 18 char *cto = to; 19 const char *cfrom = from; 20 *cto++ = *cfrom++; 21 to = cto; 22 from = cfrom; 23 n--; 24 } 25 #if defined(CONFIG_M68000) 26 if ((long)from & 1) { 27 char *cto = to; 28 const char *cfrom = from; 29 for (; n; n--) 30 *cto++ = *cfrom++; 31 return xto; 32 } 33 #endif 34 if (n > 2 && (long)to & 2) { 35 short *sto = to; 36 const short *sfrom = from; 37 *sto++ = *sfrom++; 38 to = sto; 39 from = sfrom; 40 n -= 2; 41 } 42 temp = n >> 2; 43 if (temp) { 44 long *lto = to; 45 const long *lfrom = from; 46 #if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE) 47 for (; temp; temp--) 48 *lto++ = *lfrom++; 49 #else 50 size_t temp1; 51 asm volatile ( 52 " movel %2,%3\n" 53 " andw #7,%3\n" 54 " lsrl #3,%2\n" 55 " negw %3\n" 56 " jmp %%pc@(1f,%3:w:2)\n" 57 "4: movel %0@+,%1@+\n" 58 " movel %0@+,%1@+\n" 59 " movel %0@+,%1@+\n" 60 " movel %0@+,%1@+\n" 61 " movel %0@+,%1@+\n" 62 " movel %0@+,%1@+\n" 63 " movel %0@+,%1@+\n" 64 " movel %0@+,%1@+\n" 65 "1: dbra %2,4b\n" 66 " clrw %2\n" 67 " subql #1,%2\n" 68 " jpl 4b" 69 : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1) 70 : "0" (lfrom), "1" (lto), "2" (temp)); 71 #endif 72 to = lto; 73 from = lfrom; 74 } 75 if (n & 2) { 76 short *sto = to; 77 const short *sfrom = from; 78 *sto++ = *sfrom++; 79 to = sto; 80 from = sfrom; 81 } 82 if (n & 1) { 83 char *cto = to; 84 const char *cfrom = from; 85 *cto = *cfrom; 86 } 87 return xto; 88 } 89 EXPORT_SYMBOL(memcpy); 90