aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/lib')
-rw-r--r--arch/m68k/lib/Makefile8
-rw-r--r--arch/m68k/lib/ashldi3.c62
-rw-r--r--arch/m68k/lib/ashrdi3.c63
-rw-r--r--arch/m68k/lib/checksum.c422
-rw-r--r--arch/m68k/lib/lshrdi3.c62
-rw-r--r--arch/m68k/lib/memcmp.c11
-rw-r--r--arch/m68k/lib/memcpy.c75
-rw-r--r--arch/m68k/lib/memset.c68
-rw-r--r--arch/m68k/lib/muldi3.c63
-rw-r--r--arch/m68k/lib/semaphore.S53
10 files changed, 887 insertions, 0 deletions
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile
new file mode 100644
index 000000000000..34b6dbc29c85
--- /dev/null
+++ b/arch/m68k/lib/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for m68k-specific library files..
3#
4
5EXTRA_AFLAGS := -traditional
6
7lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
8 checksum.o memcmp.o memcpy.o memset.o semaphore.o
diff --git a/arch/m68k/lib/ashldi3.c b/arch/m68k/lib/ashldi3.c
new file mode 100644
index 000000000000..7729f33878d1
--- /dev/null
+++ b/arch/m68k/lib/ashldi3.c
@@ -0,0 +1,62 @@
1/* ashrdi3.c extracted from gcc-2.95.2/libgcc2.c which is: */
2/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21#define BITS_PER_UNIT 8
22
23typedef int SItype __attribute__ ((mode (SI)));
24typedef unsigned int USItype __attribute__ ((mode (SI)));
25typedef int DItype __attribute__ ((mode (DI)));
26typedef int word_type __attribute__ ((mode (__word__)));
27
28struct DIstruct {SItype high, low;};
29
30typedef union
31{
32 struct DIstruct s;
33 DItype ll;
34} DIunion;
35
36DItype
37__ashldi3 (DItype u, word_type b)
38{
39 DIunion w;
40 word_type bm;
41 DIunion uu;
42
43 if (b == 0)
44 return u;
45
46 uu.ll = u;
47
48 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
49 if (bm <= 0)
50 {
51 w.s.low = 0;
52 w.s.high = (USItype)uu.s.low << -bm;
53 }
54 else
55 {
56 USItype carries = (USItype)uu.s.low >> bm;
57 w.s.low = (USItype)uu.s.low << b;
58 w.s.high = ((USItype)uu.s.high << b) | carries;
59 }
60
61 return w.ll;
62}
diff --git a/arch/m68k/lib/ashrdi3.c b/arch/m68k/lib/ashrdi3.c
new file mode 100644
index 000000000000..18ea5f7ed921
--- /dev/null
+++ b/arch/m68k/lib/ashrdi3.c
@@ -0,0 +1,63 @@
1/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
2/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21#define BITS_PER_UNIT 8
22
23typedef int SItype __attribute__ ((mode (SI)));
24typedef unsigned int USItype __attribute__ ((mode (SI)));
25typedef int DItype __attribute__ ((mode (DI)));
26typedef int word_type __attribute__ ((mode (__word__)));
27
28struct DIstruct {SItype high, low;};
29
30typedef union
31{
32 struct DIstruct s;
33 DItype ll;
34} DIunion;
35
36DItype
37__ashrdi3 (DItype u, word_type b)
38{
39 DIunion w;
40 word_type bm;
41 DIunion uu;
42
43 if (b == 0)
44 return u;
45
46 uu.ll = u;
47
48 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
49 if (bm <= 0)
50 {
51 /* w.s.high = 1..1 or 0..0 */
52 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
53 w.s.low = uu.s.high >> -bm;
54 }
55 else
56 {
57 USItype carries = (USItype)uu.s.high << bm;
58 w.s.high = uu.s.high >> b;
59 w.s.low = ((USItype)uu.s.low >> b) | carries;
60 }
61
62 return w.ll;
63}
diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c
new file mode 100644
index 000000000000..4a5c5445c610
--- /dev/null
+++ b/arch/m68k/lib/checksum.c
@@ -0,0 +1,422 @@
1/*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * IP/TCP/UDP checksumming routines
7 *
8 * Authors: Jorge Cwik, <jorge@laser.satlink.net>
9 * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
10 * Tom May, <ftom@netcom.com>
11 * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
12 * Lots of code moved from tcp.c and ip.c; see those files
13 * for more names.
14 *
15 * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:
16 * Fixed some nasty bugs, causing some horrible crashes.
17 * A: At some points, the sum (%0) was used as
18 * length-counter instead of the length counter
19 * (%1). Thanks to Roman Hodek for pointing this out.
20 * B: GCC seems to mess up if one uses too many
21 * data-registers to hold input values and one tries to
22 * specify d0 and d1 as scratch registers. Letting gcc
23 * choose these registers itself solves the problem.
24 *
25 * This program is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * as published by the Free Software Foundation; either version
28 * 2 of the License, or (at your option) any later version.
29 *
30 * 1998/8/31 Andreas Schwab:
31 * Zero out rest of buffer on exception in
32 * csum_partial_copy_from_user.
33 */
34
35#include <linux/module.h>
36#include <net/checksum.h>
37
38/*
39 * computes a partial checksum, e.g. for TCP/UDP fragments
40 */
41
42unsigned int
43csum_partial (const unsigned char *buff, int len, unsigned int sum)
44{
45 unsigned long tmp1, tmp2;
46 /*
47 * Experiments with ethernet and slip connections show that buff
48 * is aligned on either a 2-byte or 4-byte boundary.
49 */
50 __asm__("movel %2,%3\n\t"
51 "btst #1,%3\n\t" /* Check alignment */
52 "jeq 2f\n\t"
53 "subql #2,%1\n\t" /* buff%4==2: treat first word */
54 "jgt 1f\n\t"
55 "addql #2,%1\n\t" /* len was == 2, treat only rest */
56 "jra 4f\n"
57 "1:\t"
58 "addw %2@+,%0\n\t" /* add first word to sum */
59 "clrl %3\n\t"
60 "addxl %3,%0\n" /* add X bit */
61 "2:\t"
62 /* unrolled loop for the main part: do 8 longs at once */
63 "movel %1,%3\n\t" /* save len in tmp1 */
64 "lsrl #5,%1\n\t" /* len/32 */
65 "jeq 2f\n\t" /* not enough... */
66 "subql #1,%1\n"
67 "1:\t"
68 "movel %2@+,%4\n\t"
69 "addxl %4,%0\n\t"
70 "movel %2@+,%4\n\t"
71 "addxl %4,%0\n\t"
72 "movel %2@+,%4\n\t"
73 "addxl %4,%0\n\t"
74 "movel %2@+,%4\n\t"
75 "addxl %4,%0\n\t"
76 "movel %2@+,%4\n\t"
77 "addxl %4,%0\n\t"
78 "movel %2@+,%4\n\t"
79 "addxl %4,%0\n\t"
80 "movel %2@+,%4\n\t"
81 "addxl %4,%0\n\t"
82 "movel %2@+,%4\n\t"
83 "addxl %4,%0\n\t"
84 "dbra %1,1b\n\t"
85 "clrl %4\n\t"
86 "addxl %4,%0\n\t" /* add X bit */
87 "clrw %1\n\t"
88 "subql #1,%1\n\t"
89 "jcc 1b\n"
90 "2:\t"
91 "movel %3,%1\n\t" /* restore len from tmp1 */
92 "andw #0x1c,%3\n\t" /* number of rest longs */
93 "jeq 4f\n\t"
94 "lsrw #2,%3\n\t"
95 "subqw #1,%3\n"
96 "3:\t"
97 /* loop for rest longs */
98 "movel %2@+,%4\n\t"
99 "addxl %4,%0\n\t"
100 "dbra %3,3b\n\t"
101 "clrl %4\n\t"
102 "addxl %4,%0\n" /* add X bit */
103 "4:\t"
104 /* now check for rest bytes that do not fit into longs */
105 "andw #3,%1\n\t"
106 "jeq 7f\n\t"
107 "clrl %4\n\t" /* clear tmp2 for rest bytes */
108 "subqw #2,%1\n\t"
109 "jlt 5f\n\t"
110 "movew %2@+,%4\n\t" /* have rest >= 2: get word */
111 "swap %4\n\t" /* into bits 16..31 */
112 "tstw %1\n\t" /* another byte? */
113 "jeq 6f\n"
114 "5:\t"
115 "moveb %2@,%4\n\t" /* have odd rest: get byte */
116 "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */
117 "6:\t"
118 "addl %4,%0\n\t" /* now add rest long to sum */
119 "clrl %4\n\t"
120 "addxl %4,%0\n" /* add X bit */
121 "7:\t"
122 : "=d" (sum), "=d" (len), "=a" (buff),
123 "=&d" (tmp1), "=&d" (tmp2)
124 : "0" (sum), "1" (len), "2" (buff)
125 );
126 return(sum);
127}
128
129EXPORT_SYMBOL(csum_partial);
130
131
132/*
133 * copy from user space while checksumming, with exception handling.
134 */
135
136unsigned int
137csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
138 int len, int sum, int *csum_err)
139{
140 /*
141 * GCC doesn't like more than 10 operands for the asm
142 * statements so we have to use tmp2 for the error
143 * code.
144 */
145 unsigned long tmp1, tmp2;
146
147 __asm__("movel %2,%4\n\t"
148 "btst #1,%4\n\t" /* Check alignment */
149 "jeq 2f\n\t"
150 "subql #2,%1\n\t" /* buff%4==2: treat first word */
151 "jgt 1f\n\t"
152 "addql #2,%1\n\t" /* len was == 2, treat only rest */
153 "jra 4f\n"
154 "1:\n"
155 "10:\t"
156 "movesw %2@+,%4\n\t" /* add first word to sum */
157 "addw %4,%0\n\t"
158 "movew %4,%3@+\n\t"
159 "clrl %4\n\t"
160 "addxl %4,%0\n" /* add X bit */
161 "2:\t"
162 /* unrolled loop for the main part: do 8 longs at once */
163 "movel %1,%4\n\t" /* save len in tmp1 */
164 "lsrl #5,%1\n\t" /* len/32 */
165 "jeq 2f\n\t" /* not enough... */
166 "subql #1,%1\n"
167 "1:\n"
168 "11:\t"
169 "movesl %2@+,%5\n\t"
170 "addxl %5,%0\n\t"
171 "movel %5,%3@+\n\t"
172 "12:\t"
173 "movesl %2@+,%5\n\t"
174 "addxl %5,%0\n\t"
175 "movel %5,%3@+\n\t"
176 "13:\t"
177 "movesl %2@+,%5\n\t"
178 "addxl %5,%0\n\t"
179 "movel %5,%3@+\n\t"
180 "14:\t"
181 "movesl %2@+,%5\n\t"
182 "addxl %5,%0\n\t"
183 "movel %5,%3@+\n\t"
184 "15:\t"
185 "movesl %2@+,%5\n\t"
186 "addxl %5,%0\n\t"
187 "movel %5,%3@+\n\t"
188 "16:\t"
189 "movesl %2@+,%5\n\t"
190 "addxl %5,%0\n\t"
191 "movel %5,%3@+\n\t"
192 "17:\t"
193 "movesl %2@+,%5\n\t"
194 "addxl %5,%0\n\t"
195 "movel %5,%3@+\n\t"
196 "18:\t"
197 "movesl %2@+,%5\n\t"
198 "addxl %5,%0\n\t"
199 "movel %5,%3@+\n\t"
200 "dbra %1,1b\n\t"
201 "clrl %5\n\t"
202 "addxl %5,%0\n\t" /* add X bit */
203 "clrw %1\n\t"
204 "subql #1,%1\n\t"
205 "jcc 1b\n"
206 "2:\t"
207 "movel %4,%1\n\t" /* restore len from tmp1 */
208 "andw #0x1c,%4\n\t" /* number of rest longs */
209 "jeq 4f\n\t"
210 "lsrw #2,%4\n\t"
211 "subqw #1,%4\n"
212 "3:\n"
213 /* loop for rest longs */
214 "19:\t"
215 "movesl %2@+,%5\n\t"
216 "addxl %5,%0\n\t"
217 "movel %5,%3@+\n\t"
218 "dbra %4,3b\n\t"
219 "clrl %5\n\t"
220 "addxl %5,%0\n" /* add X bit */
221 "4:\t"
222 /* now check for rest bytes that do not fit into longs */
223 "andw #3,%1\n\t"
224 "jeq 7f\n\t"
225 "clrl %5\n\t" /* clear tmp2 for rest bytes */
226 "subqw #2,%1\n\t"
227 "jlt 5f\n\t"
228 "20:\t"
229 "movesw %2@+,%5\n\t" /* have rest >= 2: get word */
230 "movew %5,%3@+\n\t"
231 "swap %5\n\t" /* into bits 16..31 */
232 "tstw %1\n\t" /* another byte? */
233 "jeq 6f\n"
234 "5:\n"
235 "21:\t"
236 "movesb %2@,%5\n\t" /* have odd rest: get byte */
237 "moveb %5,%3@+\n\t"
238 "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */
239 "6:\t"
240 "addl %5,%0\n\t" /* now add rest long to sum */
241 "clrl %5\n\t"
242 "addxl %5,%0\n\t" /* add X bit */
243 "7:\t"
244 "clrl %5\n" /* no error - clear return value */
245 "8:\n"
246 ".section .fixup,\"ax\"\n"
247 ".even\n"
248 /* If any exception occurs zero out the rest.
249 Similarities with the code above are intentional :-) */
250 "90:\t"
251 "clrw %3@+\n\t"
252 "movel %1,%4\n\t"
253 "lsrl #5,%1\n\t"
254 "jeq 1f\n\t"
255 "subql #1,%1\n"
256 "91:\t"
257 "clrl %3@+\n"
258 "92:\t"
259 "clrl %3@+\n"
260 "93:\t"
261 "clrl %3@+\n"
262 "94:\t"
263 "clrl %3@+\n"
264 "95:\t"
265 "clrl %3@+\n"
266 "96:\t"
267 "clrl %3@+\n"
268 "97:\t"
269 "clrl %3@+\n"
270 "98:\t"
271 "clrl %3@+\n\t"
272 "dbra %1,91b\n\t"
273 "clrw %1\n\t"
274 "subql #1,%1\n\t"
275 "jcc 91b\n"
276 "1:\t"
277 "movel %4,%1\n\t"
278 "andw #0x1c,%4\n\t"
279 "jeq 1f\n\t"
280 "lsrw #2,%4\n\t"
281 "subqw #1,%4\n"
282 "99:\t"
283 "clrl %3@+\n\t"
284 "dbra %4,99b\n\t"
285 "1:\t"
286 "andw #3,%1\n\t"
287 "jeq 9f\n"
288 "100:\t"
289 "clrw %3@+\n\t"
290 "tstw %1\n\t"
291 "jeq 9f\n"
292 "101:\t"
293 "clrb %3@+\n"
294 "9:\t"
295#define STR(X) STR1(X)
296#define STR1(X) #X
297 "moveq #-" STR(EFAULT) ",%5\n\t"
298 "jra 8b\n"
299 ".previous\n"
300 ".section __ex_table,\"a\"\n"
301 ".long 10b,90b\n"
302 ".long 11b,91b\n"
303 ".long 12b,92b\n"
304 ".long 13b,93b\n"
305 ".long 14b,94b\n"
306 ".long 15b,95b\n"
307 ".long 16b,96b\n"
308 ".long 17b,97b\n"
309 ".long 18b,98b\n"
310 ".long 19b,99b\n"
311 ".long 20b,100b\n"
312 ".long 21b,101b\n"
313 ".previous"
314 : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),
315 "=&d" (tmp1), "=d" (tmp2)
316 : "0" (sum), "1" (len), "2" (src), "3" (dst)
317 );
318
319 *csum_err = tmp2;
320
321 return(sum);
322}
323
324/*
325 * copy from kernel space while checksumming, otherwise like csum_partial
326 */
327
328unsigned int
329csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, int sum)
330{
331 unsigned long tmp1, tmp2;
332 __asm__("movel %2,%4\n\t"
333 "btst #1,%4\n\t" /* Check alignment */
334 "jeq 2f\n\t"
335 "subql #2,%1\n\t" /* buff%4==2: treat first word */
336 "jgt 1f\n\t"
337 "addql #2,%1\n\t" /* len was == 2, treat only rest */
338 "jra 4f\n"
339 "1:\t"
340 "movew %2@+,%4\n\t" /* add first word to sum */
341 "addw %4,%0\n\t"
342 "movew %4,%3@+\n\t"
343 "clrl %4\n\t"
344 "addxl %4,%0\n" /* add X bit */
345 "2:\t"
346 /* unrolled loop for the main part: do 8 longs at once */
347 "movel %1,%4\n\t" /* save len in tmp1 */
348 "lsrl #5,%1\n\t" /* len/32 */
349 "jeq 2f\n\t" /* not enough... */
350 "subql #1,%1\n"
351 "1:\t"
352 "movel %2@+,%5\n\t"
353 "addxl %5,%0\n\t"
354 "movel %5,%3@+\n\t"
355 "movel %2@+,%5\n\t"
356 "addxl %5,%0\n\t"
357 "movel %5,%3@+\n\t"
358 "movel %2@+,%5\n\t"
359 "addxl %5,%0\n\t"
360 "movel %5,%3@+\n\t"
361 "movel %2@+,%5\n\t"
362 "addxl %5,%0\n\t"
363 "movel %5,%3@+\n\t"
364 "movel %2@+,%5\n\t"
365 "addxl %5,%0\n\t"
366 "movel %5,%3@+\n\t"
367 "movel %2@+,%5\n\t"
368 "addxl %5,%0\n\t"
369 "movel %5,%3@+\n\t"
370 "movel %2@+,%5\n\t"
371 "addxl %5,%0\n\t"
372 "movel %5,%3@+\n\t"
373 "movel %2@+,%5\n\t"
374 "addxl %5,%0\n\t"
375 "movel %5,%3@+\n\t"
376 "dbra %1,1b\n\t"
377 "clrl %5\n\t"
378 "addxl %5,%0\n\t" /* add X bit */
379 "clrw %1\n\t"
380 "subql #1,%1\n\t"
381 "jcc 1b\n"
382 "2:\t"
383 "movel %4,%1\n\t" /* restore len from tmp1 */
384 "andw #0x1c,%4\n\t" /* number of rest longs */
385 "jeq 4f\n\t"
386 "lsrw #2,%4\n\t"
387 "subqw #1,%4\n"
388 "3:\t"
389 /* loop for rest longs */
390 "movel %2@+,%5\n\t"
391 "addxl %5,%0\n\t"
392 "movel %5,%3@+\n\t"
393 "dbra %4,3b\n\t"
394 "clrl %5\n\t"
395 "addxl %5,%0\n" /* add X bit */
396 "4:\t"
397 /* now check for rest bytes that do not fit into longs */
398 "andw #3,%1\n\t"
399 "jeq 7f\n\t"
400 "clrl %5\n\t" /* clear tmp2 for rest bytes */
401 "subqw #2,%1\n\t"
402 "jlt 5f\n\t"
403 "movew %2@+,%5\n\t" /* have rest >= 2: get word */
404 "movew %5,%3@+\n\t"
405 "swap %5\n\t" /* into bits 16..31 */
406 "tstw %1\n\t" /* another byte? */
407 "jeq 6f\n"
408 "5:\t"
409 "moveb %2@,%5\n\t" /* have odd rest: get byte */
410 "moveb %5,%3@+\n\t"
411 "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */
412 "6:\t"
413 "addl %5,%0\n\t" /* now add rest long to sum */
414 "clrl %5\n\t"
415 "addxl %5,%0\n" /* add X bit */
416 "7:\t"
417 : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),
418 "=&d" (tmp1), "=&d" (tmp2)
419 : "0" (sum), "1" (len), "2" (src), "3" (dst)
420 );
421 return(sum);
422}
diff --git a/arch/m68k/lib/lshrdi3.c b/arch/m68k/lib/lshrdi3.c
new file mode 100644
index 000000000000..d06442d3a328
--- /dev/null
+++ b/arch/m68k/lib/lshrdi3.c
@@ -0,0 +1,62 @@
1/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
2/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21#define BITS_PER_UNIT 8
22
23typedef int SItype __attribute__ ((mode (SI)));
24typedef unsigned int USItype __attribute__ ((mode (SI)));
25typedef int DItype __attribute__ ((mode (DI)));
26typedef int word_type __attribute__ ((mode (__word__)));
27
28struct DIstruct {SItype high, low;};
29
30typedef union
31{
32 struct DIstruct s;
33 DItype ll;
34} DIunion;
35
36DItype
37__lshrdi3 (DItype u, word_type b)
38{
39 DIunion w;
40 word_type bm;
41 DIunion uu;
42
43 if (b == 0)
44 return u;
45
46 uu.ll = u;
47
48 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
49 if (bm <= 0)
50 {
51 w.s.high = 0;
52 w.s.low = (USItype)uu.s.high >> -bm;
53 }
54 else
55 {
56 USItype carries = (USItype)uu.s.high << bm;
57 w.s.high = (USItype)uu.s.high >> b;
58 w.s.low = ((USItype)uu.s.low >> b) | carries;
59 }
60
61 return w.ll;
62}
diff --git a/arch/m68k/lib/memcmp.c b/arch/m68k/lib/memcmp.c
new file mode 100644
index 000000000000..f4796febb773
--- /dev/null
+++ b/arch/m68k/lib/memcmp.c
@@ -0,0 +1,11 @@
1#include <linux/types.h>
2
3int memcmp(const void * cs,const void * ct,size_t count)
4{
5 const unsigned char *su1, *su2;
6
7 for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
8 if (*su1 != *su2)
9 return((*su1 < *su2) ? -1 : +1);
10 return(0);
11}
diff --git a/arch/m68k/lib/memcpy.c b/arch/m68k/lib/memcpy.c
new file mode 100644
index 000000000000..73e181823d9b
--- /dev/null
+++ b/arch/m68k/lib/memcpy.c
@@ -0,0 +1,75 @@
1#include <linux/types.h>
2
3void * memcpy(void * to, const void * from, size_t n)
4{
5 void *xto = to;
6 size_t temp, temp1;
7
8 if (!n)
9 return xto;
10 if ((long) to & 1)
11 {
12 char *cto = to;
13 const char *cfrom = from;
14 *cto++ = *cfrom++;
15 to = cto;
16 from = cfrom;
17 n--;
18 }
19 if (n > 2 && (long) to & 2)
20 {
21 short *sto = to;
22 const short *sfrom = from;
23 *sto++ = *sfrom++;
24 to = sto;
25 from = sfrom;
26 n -= 2;
27 }
28 temp = n >> 2;
29 if (temp)
30 {
31 long *lto = to;
32 const long *lfrom = from;
33
34 __asm__ __volatile__("movel %2,%3\n\t"
35 "andw #7,%3\n\t"
36 "lsrl #3,%2\n\t"
37 "negw %3\n\t"
38 "jmp %%pc@(1f,%3:w:2)\n\t"
39 "4:\t"
40 "movel %0@+,%1@+\n\t"
41 "movel %0@+,%1@+\n\t"
42 "movel %0@+,%1@+\n\t"
43 "movel %0@+,%1@+\n\t"
44 "movel %0@+,%1@+\n\t"
45 "movel %0@+,%1@+\n\t"
46 "movel %0@+,%1@+\n\t"
47 "movel %0@+,%1@+\n\t"
48 "1:\t"
49 "dbra %2,4b\n\t"
50 "clrw %2\n\t"
51 "subql #1,%2\n\t"
52 "jpl 4b\n\t"
53 : "=a" (lfrom), "=a" (lto), "=d" (temp),
54 "=&d" (temp1)
55 : "0" (lfrom), "1" (lto), "2" (temp)
56 );
57 to = lto;
58 from = lfrom;
59 }
60 if (n & 2)
61 {
62 short *sto = to;
63 const short *sfrom = from;
64 *sto++ = *sfrom++;
65 to = sto;
66 from = sfrom;
67 }
68 if (n & 1)
69 {
70 char *cto = to;
71 const char *cfrom = from;
72 *cto = *cfrom;
73 }
74 return xto;
75}
diff --git a/arch/m68k/lib/memset.c b/arch/m68k/lib/memset.c
new file mode 100644
index 000000000000..d55fdb2ee9d3
--- /dev/null
+++ b/arch/m68k/lib/memset.c
@@ -0,0 +1,68 @@
1#include <linux/types.h>
2
3void * memset(void * s, int c, size_t count)
4{
5 void *xs = s;
6 size_t temp, temp1;
7
8 if (!count)
9 return xs;
10 c &= 0xff;
11 c |= c << 8;
12 c |= c << 16;
13 if ((long) s & 1)
14 {
15 char *cs = s;
16 *cs++ = c;
17 s = cs;
18 count--;
19 }
20 if (count > 2 && (long) s & 2)
21 {
22 short *ss = s;
23 *ss++ = c;
24 s = ss;
25 count -= 2;
26 }
27 temp = count >> 2;
28 if (temp)
29 {
30 long *ls = s;
31
32 __asm__ __volatile__("movel %1,%2\n\t"
33 "andw #7,%2\n\t"
34 "lsrl #3,%1\n\t"
35 "negw %2\n\t"
36 "jmp %%pc@(2f,%2:w:2)\n\t"
37 "1:\t"
38 "movel %3,%0@+\n\t"
39 "movel %3,%0@+\n\t"
40 "movel %3,%0@+\n\t"
41 "movel %3,%0@+\n\t"
42 "movel %3,%0@+\n\t"
43 "movel %3,%0@+\n\t"
44 "movel %3,%0@+\n\t"
45 "movel %3,%0@+\n\t"
46 "2:\t"
47 "dbra %1,1b\n\t"
48 "clrw %1\n\t"
49 "subql #1,%1\n\t"
50 "jpl 1b\n\t"
51 : "=a" (ls), "=d" (temp), "=&d" (temp1)
52 : "d" (c), "0" (ls), "1" (temp)
53 );
54 s = ls;
55 }
56 if (count & 2)
57 {
58 short *ss = s;
59 *ss++ = c;
60 s = ss;
61 }
62 if (count & 1)
63 {
64 char *cs = s;
65 *cs = c;
66 }
67 return xs;
68}
diff --git a/arch/m68k/lib/muldi3.c b/arch/m68k/lib/muldi3.c
new file mode 100644
index 000000000000..be4f275649e3
--- /dev/null
+++ b/arch/m68k/lib/muldi3.c
@@ -0,0 +1,63 @@
1/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and
2 gcc-2.7.2.3/longlong.h which is: */
3/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22#define BITS_PER_UNIT 8
23
24#define umul_ppmm(w1, w0, u, v) \
25 __asm__ ("mulu%.l %3,%1:%0" \
26 : "=d" ((USItype)(w0)), \
27 "=d" ((USItype)(w1)) \
28 : "%0" ((USItype)(u)), \
29 "dmi" ((USItype)(v)))
30
31#define __umulsidi3(u, v) \
32 ({DIunion __w; \
33 umul_ppmm (__w.s.high, __w.s.low, u, v); \
34 __w.ll; })
35
36typedef int SItype __attribute__ ((mode (SI)));
37typedef unsigned int USItype __attribute__ ((mode (SI)));
38typedef int DItype __attribute__ ((mode (DI)));
39typedef int word_type __attribute__ ((mode (__word__)));
40
41struct DIstruct {SItype high, low;};
42
43typedef union
44{
45 struct DIstruct s;
46 DItype ll;
47} DIunion;
48
49DItype
50__muldi3 (DItype u, DItype v)
51{
52 DIunion w;
53 DIunion uu, vv;
54
55 uu.ll = u,
56 vv.ll = v;
57
58 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
59 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
60 + (USItype) uu.s.high * (USItype) vv.s.low);
61
62 return w.ll;
63}
diff --git a/arch/m68k/lib/semaphore.S b/arch/m68k/lib/semaphore.S
new file mode 100644
index 000000000000..0215624c1602
--- /dev/null
+++ b/arch/m68k/lib/semaphore.S
@@ -0,0 +1,53 @@
1/*
2 * linux/arch/m68k/lib/semaphore.S
3 *
4 * Copyright (C) 1996 Linus Torvalds
5 *
6 * m68k version by Andreas Schwab
7 */
8
9#include <linux/linkage.h>
10#include <asm/semaphore.h>
11
12/*
13 * The semaphore operations have a special calling sequence that
14 * allow us to do a simpler in-line version of them. These routines
15 * need to convert that sequence back into the C sequence when
16 * there is contention on the semaphore.
17 */
18ENTRY(__down_failed)
19 moveml %a0/%d0/%d1,-(%sp)
20 movel %a1,-(%sp)
21 jbsr __down
22 movel (%sp)+,%a1
23 moveml (%sp)+,%a0/%d0/%d1
24 rts
25
26ENTRY(__down_failed_interruptible)
27 movel %a0,-(%sp)
28 movel %d1,-(%sp)
29 movel %a1,-(%sp)
30 jbsr __down_interruptible
31 movel (%sp)+,%a1
32 movel (%sp)+,%d1
33 movel (%sp)+,%a0
34 rts
35
36ENTRY(__down_failed_trylock)
37 movel %a0,-(%sp)
38 movel %d1,-(%sp)
39 movel %a1,-(%sp)
40 jbsr __down_trylock
41 movel (%sp)+,%a1
42 movel (%sp)+,%d1
43 movel (%sp)+,%a0
44 rts
45
46ENTRY(__up_wakeup)
47 moveml %a0/%d0/%d1,-(%sp)
48 movel %a1,-(%sp)
49 jbsr __up
50 movel (%sp)+,%a1
51 moveml (%sp)+,%a0/%d0/%d1
52 rts
53