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 | |