diff options
author | Roman Zippel <zippel@linux-m68k.org> | 2005-09-03 18:57:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:06:19 -0400 |
commit | 072dffda1d35c391fe893ec9b1d098145e668fef (patch) | |
tree | 2eee1530619abb7cf751db022216ab483e6fc823 /arch/m68k/lib/string.c | |
parent | 2855b97020f6d4a4dfb005fb77c0b79c8cb9d13f (diff) |
[PATCH] m68k: cleanup inline mem functions
Use the builtin functions for memset/memclr/memcpy, special optimizations for
page operations have dedicated functions now. Uninline memmove/memchr and
move all functions into a single file and clean it up a little.
Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/m68k/lib/string.c')
-rw-r--r-- | arch/m68k/lib/string.c | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/arch/m68k/lib/string.c b/arch/m68k/lib/string.c new file mode 100644 index 000000000000..b92b89e1ea0c --- /dev/null +++ b/arch/m68k/lib/string.c | |||
@@ -0,0 +1,237 @@ | |||
1 | |||
2 | #include <linux/types.h> | ||
3 | #include <linux/module.h> | ||
4 | |||
5 | void *memset(void *s, int c, size_t count) | ||
6 | { | ||
7 | void *xs = s; | ||
8 | size_t temp, temp1; | ||
9 | |||
10 | if (!count) | ||
11 | return xs; | ||
12 | c &= 0xff; | ||
13 | c |= c << 8; | ||
14 | c |= c << 16; | ||
15 | if ((long)s & 1) { | ||
16 | char *cs = s; | ||
17 | *cs++ = c; | ||
18 | s = cs; | ||
19 | count--; | ||
20 | } | ||
21 | if (count > 2 && (long)s & 2) { | ||
22 | short *ss = s; | ||
23 | *ss++ = c; | ||
24 | s = ss; | ||
25 | count -= 2; | ||
26 | } | ||
27 | temp = count >> 2; | ||
28 | if (temp) { | ||
29 | long *ls = s; | ||
30 | |||
31 | asm volatile ( | ||
32 | " movel %1,%2\n" | ||
33 | " andw #7,%2\n" | ||
34 | " lsrl #3,%1\n" | ||
35 | " negw %2\n" | ||
36 | " jmp %%pc@(2f,%2:w:2)\n" | ||
37 | "1: movel %3,%0@+\n" | ||
38 | " movel %3,%0@+\n" | ||
39 | " movel %3,%0@+\n" | ||
40 | " movel %3,%0@+\n" | ||
41 | " movel %3,%0@+\n" | ||
42 | " movel %3,%0@+\n" | ||
43 | " movel %3,%0@+\n" | ||
44 | " movel %3,%0@+\n" | ||
45 | "2: dbra %1,1b\n" | ||
46 | " clrw %1\n" | ||
47 | " subql #1,%1\n" | ||
48 | " jpl 1b" | ||
49 | : "=a" (ls), "=d" (temp), "=&d" (temp1) | ||
50 | : "d" (c), "0" (ls), "1" (temp)); | ||
51 | s = ls; | ||
52 | } | ||
53 | if (count & 2) { | ||
54 | short *ss = s; | ||
55 | *ss++ = c; | ||
56 | s = ss; | ||
57 | } | ||
58 | if (count & 1) { | ||
59 | char *cs = s; | ||
60 | *cs = c; | ||
61 | } | ||
62 | return xs; | ||
63 | } | ||
64 | EXPORT_SYMBOL(memset); | ||
65 | |||
66 | void *memcpy(void *to, const void *from, size_t n) | ||
67 | { | ||
68 | void *xto = to; | ||
69 | size_t temp, temp1; | ||
70 | |||
71 | if (!n) | ||
72 | return xto; | ||
73 | if ((long)to & 1) { | ||
74 | char *cto = to; | ||
75 | const char *cfrom = from; | ||
76 | *cto++ = *cfrom++; | ||
77 | to = cto; | ||
78 | from = cfrom; | ||
79 | n--; | ||
80 | } | ||
81 | if (n > 2 && (long)to & 2) { | ||
82 | short *sto = to; | ||
83 | const short *sfrom = from; | ||
84 | *sto++ = *sfrom++; | ||
85 | to = sto; | ||
86 | from = sfrom; | ||
87 | n -= 2; | ||
88 | } | ||
89 | temp = n >> 2; | ||
90 | if (temp) { | ||
91 | long *lto = to; | ||
92 | const long *lfrom = from; | ||
93 | |||
94 | asm volatile ( | ||
95 | " movel %2,%3\n" | ||
96 | " andw #7,%3\n" | ||
97 | " lsrl #3,%2\n" | ||
98 | " negw %3\n" | ||
99 | " jmp %%pc@(1f,%3:w:2)\n" | ||
100 | "4: movel %0@+,%1@+\n" | ||
101 | " movel %0@+,%1@+\n" | ||
102 | " movel %0@+,%1@+\n" | ||
103 | " movel %0@+,%1@+\n" | ||
104 | " movel %0@+,%1@+\n" | ||
105 | " movel %0@+,%1@+\n" | ||
106 | " movel %0@+,%1@+\n" | ||
107 | " movel %0@+,%1@+\n" | ||
108 | "1: dbra %2,4b\n" | ||
109 | " clrw %2\n" | ||
110 | " subql #1,%2\n" | ||
111 | " jpl 4b" | ||
112 | : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1) | ||
113 | : "0" (lfrom), "1" (lto), "2" (temp)); | ||
114 | to = lto; | ||
115 | from = lfrom; | ||
116 | } | ||
117 | if (n & 2) { | ||
118 | short *sto = to; | ||
119 | const short *sfrom = from; | ||
120 | *sto++ = *sfrom++; | ||
121 | to = sto; | ||
122 | from = sfrom; | ||
123 | } | ||
124 | if (n & 1) { | ||
125 | char *cto = to; | ||
126 | const char *cfrom = from; | ||
127 | *cto = *cfrom; | ||
128 | } | ||
129 | return xto; | ||
130 | } | ||
131 | EXPORT_SYMBOL(memcpy); | ||
132 | |||
133 | void *memmove(void *dest, const void *src, size_t n) | ||
134 | { | ||
135 | void *xdest = dest; | ||
136 | size_t temp; | ||
137 | |||
138 | if (!n) | ||
139 | return xdest; | ||
140 | |||
141 | if (dest < src) { | ||
142 | if ((long)dest & 1) { | ||
143 | char *cdest = dest; | ||
144 | const char *csrc = src; | ||
145 | *cdest++ = *csrc++; | ||
146 | dest = cdest; | ||
147 | src = csrc; | ||
148 | n--; | ||
149 | } | ||
150 | if (n > 2 && (long)dest & 2) { | ||
151 | short *sdest = dest; | ||
152 | const short *ssrc = src; | ||
153 | *sdest++ = *ssrc++; | ||
154 | dest = sdest; | ||
155 | src = ssrc; | ||
156 | n -= 2; | ||
157 | } | ||
158 | temp = n >> 2; | ||
159 | if (temp) { | ||
160 | long *ldest = dest; | ||
161 | const long *lsrc = src; | ||
162 | temp--; | ||
163 | do | ||
164 | *ldest++ = *lsrc++; | ||
165 | while (temp--); | ||
166 | dest = ldest; | ||
167 | src = lsrc; | ||
168 | } | ||
169 | if (n & 2) { | ||
170 | short *sdest = dest; | ||
171 | const short *ssrc = src; | ||
172 | *sdest++ = *ssrc++; | ||
173 | dest = sdest; | ||
174 | src = ssrc; | ||
175 | } | ||
176 | if (n & 1) { | ||
177 | char *cdest = dest; | ||
178 | const char *csrc = src; | ||
179 | *cdest = *csrc; | ||
180 | } | ||
181 | } else { | ||
182 | dest = (char *)dest + n; | ||
183 | src = (const char *)src + n; | ||
184 | if ((long)dest & 1) { | ||
185 | char *cdest = dest; | ||
186 | const char *csrc = src; | ||
187 | *--cdest = *--csrc; | ||
188 | dest = cdest; | ||
189 | src = csrc; | ||
190 | n--; | ||
191 | } | ||
192 | if (n > 2 && (long)dest & 2) { | ||
193 | short *sdest = dest; | ||
194 | const short *ssrc = src; | ||
195 | *--sdest = *--ssrc; | ||
196 | dest = sdest; | ||
197 | src = ssrc; | ||
198 | n -= 2; | ||
199 | } | ||
200 | temp = n >> 2; | ||
201 | if (temp) { | ||
202 | long *ldest = dest; | ||
203 | const long *lsrc = src; | ||
204 | temp--; | ||
205 | do | ||
206 | *--ldest = *--lsrc; | ||
207 | while (temp--); | ||
208 | dest = ldest; | ||
209 | src = lsrc; | ||
210 | } | ||
211 | if (n & 2) { | ||
212 | short *sdest = dest; | ||
213 | const short *ssrc = src; | ||
214 | *--sdest = *--ssrc; | ||
215 | dest = sdest; | ||
216 | src = ssrc; | ||
217 | } | ||
218 | if (n & 1) { | ||
219 | char *cdest = dest; | ||
220 | const char *csrc = src; | ||
221 | *--cdest = *--csrc; | ||
222 | } | ||
223 | } | ||
224 | return xdest; | ||
225 | } | ||
226 | EXPORT_SYMBOL(memmove); | ||
227 | |||
228 | int memcmp(const void *cs, const void *ct, size_t count) | ||
229 | { | ||
230 | const unsigned char *su1, *su2; | ||
231 | |||
232 | for (su1 = cs, su2 = ct; count > 0; ++su1, ++su2, count--) | ||
233 | if (*su1 != *su2) | ||
234 | return *su1 < *su2 ? -1 : +1; | ||
235 | return 0; | ||
236 | } | ||
237 | EXPORT_SYMBOL(memcmp); | ||