diff options
Diffstat (limited to 'arch/m68k/lib')
-rw-r--r-- | arch/m68k/lib/Makefile | 10 | ||||
-rw-r--r-- | arch/m68k/lib/checksum_mm.c (renamed from arch/m68k/lib/checksum.c) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/checksum_no.c | 156 | ||||
-rw-r--r-- | arch/m68k/lib/delay.c | 21 | ||||
-rw-r--r-- | arch/m68k/lib/divsi3.S | 125 | ||||
-rw-r--r-- | arch/m68k/lib/memcpy.c | 79 | ||||
-rw-r--r-- | arch/m68k/lib/memmove.c | 103 | ||||
-rw-r--r-- | arch/m68k/lib/memset.c | 74 | ||||
-rw-r--r-- | arch/m68k/lib/modsi3.S | 113 | ||||
-rw-r--r-- | arch/m68k/lib/muldi3.c | 40 | ||||
-rw-r--r-- | arch/m68k/lib/mulsi3.S | 110 | ||||
-rw-r--r-- | arch/m68k/lib/string.c | 234 | ||||
-rw-r--r-- | arch/m68k/lib/udivsi3.S | 162 | ||||
-rw-r--r-- | arch/m68k/lib/umodsi3.S | 113 |
14 files changed, 1102 insertions, 238 deletions
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index af9abf8d9d98..df421e501436 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile | |||
@@ -1,6 +1,14 @@ | |||
1 | |||
1 | # | 2 | # |
2 | # Makefile for m68k-specific library files.. | 3 | # Makefile for m68k-specific library files.. |
3 | # | 4 | # |
4 | 5 | ||
5 | lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ | 6 | lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ |
6 | checksum.o string.o uaccess.o | 7 | memcpy.o memset.o memmove.o |
8 | |||
9 | ifdef CONFIG_MMU | ||
10 | lib-y += string.o uaccess.o checksum_mm.o | ||
11 | else | ||
12 | lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o delay.o checksum_no.o | ||
13 | endif | ||
14 | |||
diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum_mm.c index 6216f12a756b..6216f12a756b 100644 --- a/arch/m68k/lib/checksum.c +++ b/arch/m68k/lib/checksum_mm.c | |||
diff --git a/arch/m68k/lib/checksum_no.c b/arch/m68k/lib/checksum_no.c new file mode 100644 index 000000000000..e4c6354da765 --- /dev/null +++ b/arch/m68k/lib/checksum_no.c | |||
@@ -0,0 +1,156 @@ | |||
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 choose these | ||
23 | * 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 | |||
31 | /* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most | ||
32 | of the assembly has to go. */ | ||
33 | |||
34 | #include <linux/module.h> | ||
35 | #include <net/checksum.h> | ||
36 | |||
37 | static inline unsigned short from32to16(unsigned long x) | ||
38 | { | ||
39 | /* add up 16-bit and 16-bit for 16+c bit */ | ||
40 | x = (x & 0xffff) + (x >> 16); | ||
41 | /* add up carry.. */ | ||
42 | x = (x & 0xffff) + (x >> 16); | ||
43 | return x; | ||
44 | } | ||
45 | |||
46 | static unsigned long do_csum(const unsigned char * buff, int len) | ||
47 | { | ||
48 | int odd, count; | ||
49 | unsigned long result = 0; | ||
50 | |||
51 | if (len <= 0) | ||
52 | goto out; | ||
53 | odd = 1 & (unsigned long) buff; | ||
54 | if (odd) { | ||
55 | result = *buff; | ||
56 | len--; | ||
57 | buff++; | ||
58 | } | ||
59 | count = len >> 1; /* nr of 16-bit words.. */ | ||
60 | if (count) { | ||
61 | if (2 & (unsigned long) buff) { | ||
62 | result += *(unsigned short *) buff; | ||
63 | count--; | ||
64 | len -= 2; | ||
65 | buff += 2; | ||
66 | } | ||
67 | count >>= 1; /* nr of 32-bit words.. */ | ||
68 | if (count) { | ||
69 | unsigned long carry = 0; | ||
70 | do { | ||
71 | unsigned long w = *(unsigned long *) buff; | ||
72 | count--; | ||
73 | buff += 4; | ||
74 | result += carry; | ||
75 | result += w; | ||
76 | carry = (w > result); | ||
77 | } while (count); | ||
78 | result += carry; | ||
79 | result = (result & 0xffff) + (result >> 16); | ||
80 | } | ||
81 | if (len & 2) { | ||
82 | result += *(unsigned short *) buff; | ||
83 | buff += 2; | ||
84 | } | ||
85 | } | ||
86 | if (len & 1) | ||
87 | result += (*buff << 8); | ||
88 | result = from32to16(result); | ||
89 | if (odd) | ||
90 | result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); | ||
91 | out: | ||
92 | return result; | ||
93 | } | ||
94 | |||
95 | #ifdef CONFIG_COLDFIRE | ||
96 | /* | ||
97 | * This is a version of ip_compute_csum() optimized for IP headers, | ||
98 | * which always checksum on 4 octet boundaries. | ||
99 | */ | ||
100 | __sum16 ip_fast_csum(const void *iph, unsigned int ihl) | ||
101 | { | ||
102 | return (__force __sum16)~do_csum(iph,ihl*4); | ||
103 | } | ||
104 | EXPORT_SYMBOL(ip_fast_csum); | ||
105 | #endif | ||
106 | |||
107 | /* | ||
108 | * computes the checksum of a memory block at buff, length len, | ||
109 | * and adds in "sum" (32-bit) | ||
110 | * | ||
111 | * returns a 32-bit number suitable for feeding into itself | ||
112 | * or csum_tcpudp_magic | ||
113 | * | ||
114 | * this function must be called with even lengths, except | ||
115 | * for the last fragment, which may be odd | ||
116 | * | ||
117 | * it's best to have buff aligned on a 32-bit boundary | ||
118 | */ | ||
119 | __wsum csum_partial(const void *buff, int len, __wsum sum) | ||
120 | { | ||
121 | unsigned int result = do_csum(buff, len); | ||
122 | |||
123 | /* add in old sum, and carry.. */ | ||
124 | result += (__force u32)sum; | ||
125 | if ((__force u32)sum > result) | ||
126 | result += 1; | ||
127 | return (__force __wsum)result; | ||
128 | } | ||
129 | |||
130 | EXPORT_SYMBOL(csum_partial); | ||
131 | |||
132 | /* | ||
133 | * copy from fs while checksumming, otherwise like csum_partial | ||
134 | */ | ||
135 | |||
136 | __wsum | ||
137 | csum_partial_copy_from_user(const void __user *src, void *dst, | ||
138 | int len, __wsum sum, int *csum_err) | ||
139 | { | ||
140 | if (csum_err) *csum_err = 0; | ||
141 | memcpy(dst, (__force const void *)src, len); | ||
142 | return csum_partial(dst, len, sum); | ||
143 | } | ||
144 | EXPORT_SYMBOL(csum_partial_copy_from_user); | ||
145 | |||
146 | /* | ||
147 | * copy from ds while checksumming, otherwise like csum_partial | ||
148 | */ | ||
149 | |||
150 | __wsum | ||
151 | csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) | ||
152 | { | ||
153 | memcpy(dst, src, len); | ||
154 | return csum_partial(dst, len, sum); | ||
155 | } | ||
156 | EXPORT_SYMBOL(csum_partial_copy_nocheck); | ||
diff --git a/arch/m68k/lib/delay.c b/arch/m68k/lib/delay.c new file mode 100644 index 000000000000..5bd5472d38a0 --- /dev/null +++ b/arch/m68k/lib/delay.c | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * arch/m68knommu/lib/delay.c | ||
3 | * | ||
4 | * (C) Copyright 2004, Greg Ungerer <gerg@snapgear.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <asm/param.h> | ||
13 | #include <asm/delay.h> | ||
14 | |||
15 | EXPORT_SYMBOL(udelay); | ||
16 | |||
17 | void udelay(unsigned long usecs) | ||
18 | { | ||
19 | _udelay(usecs); | ||
20 | } | ||
21 | |||
diff --git a/arch/m68k/lib/divsi3.S b/arch/m68k/lib/divsi3.S new file mode 100644 index 000000000000..ec307b61991e --- /dev/null +++ b/arch/m68k/lib/divsi3.S | |||
@@ -0,0 +1,125 @@ | |||
1 | /* libgcc1 routines for 68000 w/o floating-point hardware. | ||
2 | Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc. | ||
3 | |||
4 | This file is part of GNU CC. | ||
5 | |||
6 | GNU CC is free software; you can redistribute it and/or modify it | ||
7 | under the terms of the GNU General Public License as published by the | ||
8 | Free Software Foundation; either version 2, or (at your option) any | ||
9 | later version. | ||
10 | |||
11 | In addition to the permissions in the GNU General Public License, the | ||
12 | Free Software Foundation gives you unlimited permission to link the | ||
13 | compiled version of this file with other programs, and to distribute | ||
14 | those programs without any restriction coming from the use of this | ||
15 | file. (The General Public License restrictions do apply in other | ||
16 | respects; for example, they cover modification of the file, and | ||
17 | distribution when not linked into another program.) | ||
18 | |||
19 | This file is distributed in the hope that it will be useful, but | ||
20 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
22 | General Public License for more details. | ||
23 | |||
24 | You should have received a copy of the GNU General Public License | ||
25 | along with this program; see the file COPYING. If not, write to | ||
26 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
27 | Boston, MA 02111-1307, USA. */ | ||
28 | |||
29 | /* As a special exception, if you link this library with files | ||
30 | compiled with GCC to produce an executable, this does not cause | ||
31 | the resulting executable to be covered by the GNU General Public License. | ||
32 | This exception does not however invalidate any other reasons why | ||
33 | the executable file might be covered by the GNU General Public License. */ | ||
34 | |||
35 | /* Use this one for any 680x0; assumes no floating point hardware. | ||
36 | The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk. | ||
37 | Some of this code comes from MINIX, via the folks at ericsson. | ||
38 | D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992 | ||
39 | */ | ||
40 | |||
41 | /* These are predefined by new versions of GNU cpp. */ | ||
42 | |||
43 | #ifndef __USER_LABEL_PREFIX__ | ||
44 | #define __USER_LABEL_PREFIX__ _ | ||
45 | #endif | ||
46 | |||
47 | #ifndef __REGISTER_PREFIX__ | ||
48 | #define __REGISTER_PREFIX__ | ||
49 | #endif | ||
50 | |||
51 | #ifndef __IMMEDIATE_PREFIX__ | ||
52 | #define __IMMEDIATE_PREFIX__ # | ||
53 | #endif | ||
54 | |||
55 | /* ANSI concatenation macros. */ | ||
56 | |||
57 | #define CONCAT1(a, b) CONCAT2(a, b) | ||
58 | #define CONCAT2(a, b) a ## b | ||
59 | |||
60 | /* Use the right prefix for global labels. */ | ||
61 | |||
62 | #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) | ||
63 | |||
64 | /* Use the right prefix for registers. */ | ||
65 | |||
66 | #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) | ||
67 | |||
68 | /* Use the right prefix for immediate values. */ | ||
69 | |||
70 | #define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x) | ||
71 | |||
72 | #define d0 REG (d0) | ||
73 | #define d1 REG (d1) | ||
74 | #define d2 REG (d2) | ||
75 | #define d3 REG (d3) | ||
76 | #define d4 REG (d4) | ||
77 | #define d5 REG (d5) | ||
78 | #define d6 REG (d6) | ||
79 | #define d7 REG (d7) | ||
80 | #define a0 REG (a0) | ||
81 | #define a1 REG (a1) | ||
82 | #define a2 REG (a2) | ||
83 | #define a3 REG (a3) | ||
84 | #define a4 REG (a4) | ||
85 | #define a5 REG (a5) | ||
86 | #define a6 REG (a6) | ||
87 | #define fp REG (fp) | ||
88 | #define sp REG (sp) | ||
89 | |||
90 | .text | ||
91 | .proc | ||
92 | .globl SYM (__divsi3) | ||
93 | SYM (__divsi3): | ||
94 | movel d2, sp@- | ||
95 | |||
96 | moveq IMM (1), d2 /* sign of result stored in d2 (=1 or =-1) */ | ||
97 | movel sp@(12), d1 /* d1 = divisor */ | ||
98 | jpl L1 | ||
99 | negl d1 | ||
100 | #if !(defined(__mcf5200__) || defined(__mcoldfire__)) | ||
101 | negb d2 /* change sign because divisor <0 */ | ||
102 | #else | ||
103 | negl d2 /* change sign because divisor <0 */ | ||
104 | #endif | ||
105 | L1: movel sp@(8), d0 /* d0 = dividend */ | ||
106 | jpl L2 | ||
107 | negl d0 | ||
108 | #if !(defined(__mcf5200__) || defined(__mcoldfire__)) | ||
109 | negb d2 | ||
110 | #else | ||
111 | negl d2 | ||
112 | #endif | ||
113 | |||
114 | L2: movel d1, sp@- | ||
115 | movel d0, sp@- | ||
116 | jbsr SYM (__udivsi3) /* divide abs(dividend) by abs(divisor) */ | ||
117 | addql IMM (8), sp | ||
118 | |||
119 | tstb d2 | ||
120 | jpl L3 | ||
121 | negl d0 | ||
122 | |||
123 | L3: movel sp@+, d2 | ||
124 | rts | ||
125 | |||
diff --git a/arch/m68k/lib/memcpy.c b/arch/m68k/lib/memcpy.c new file mode 100644 index 000000000000..064889316974 --- /dev/null +++ b/arch/m68k/lib/memcpy.c | |||
@@ -0,0 +1,79 @@ | |||
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, temp1; | ||
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 (n > 2 && (long)to & 2) { | ||
26 | short *sto = to; | ||
27 | const short *sfrom = from; | ||
28 | *sto++ = *sfrom++; | ||
29 | to = sto; | ||
30 | from = sfrom; | ||
31 | n -= 2; | ||
32 | } | ||
33 | temp = n >> 2; | ||
34 | if (temp) { | ||
35 | long *lto = to; | ||
36 | const long *lfrom = from; | ||
37 | #if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE) | ||
38 | for (; temp; temp--) | ||
39 | *lto++ = *lfrom++; | ||
40 | #else | ||
41 | asm volatile ( | ||
42 | " movel %2,%3\n" | ||
43 | " andw #7,%3\n" | ||
44 | " lsrl #3,%2\n" | ||
45 | " negw %3\n" | ||
46 | " jmp %%pc@(1f,%3:w:2)\n" | ||
47 | "4: movel %0@+,%1@+\n" | ||
48 | " movel %0@+,%1@+\n" | ||
49 | " movel %0@+,%1@+\n" | ||
50 | " movel %0@+,%1@+\n" | ||
51 | " movel %0@+,%1@+\n" | ||
52 | " movel %0@+,%1@+\n" | ||
53 | " movel %0@+,%1@+\n" | ||
54 | " movel %0@+,%1@+\n" | ||
55 | "1: dbra %2,4b\n" | ||
56 | " clrw %2\n" | ||
57 | " subql #1,%2\n" | ||
58 | " jpl 4b" | ||
59 | : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1) | ||
60 | : "0" (lfrom), "1" (lto), "2" (temp)); | ||
61 | #endif | ||
62 | to = lto; | ||
63 | from = lfrom; | ||
64 | } | ||
65 | if (n & 2) { | ||
66 | short *sto = to; | ||
67 | const short *sfrom = from; | ||
68 | *sto++ = *sfrom++; | ||
69 | to = sto; | ||
70 | from = sfrom; | ||
71 | } | ||
72 | if (n & 1) { | ||
73 | char *cto = to; | ||
74 | const char *cfrom = from; | ||
75 | *cto = *cfrom; | ||
76 | } | ||
77 | return xto; | ||
78 | } | ||
79 | EXPORT_SYMBOL(memcpy); | ||
diff --git a/arch/m68k/lib/memmove.c b/arch/m68k/lib/memmove.c new file mode 100644 index 000000000000..6519f7f349f6 --- /dev/null +++ b/arch/m68k/lib/memmove.c | |||
@@ -0,0 +1,103 @@ | |||
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); | ||
diff --git a/arch/m68k/lib/memset.c b/arch/m68k/lib/memset.c new file mode 100644 index 000000000000..8a7639f0a2fe --- /dev/null +++ b/arch/m68k/lib/memset.c | |||
@@ -0,0 +1,74 @@ | |||
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 *memset(void *s, int c, size_t count) | ||
11 | { | ||
12 | void *xs = s; | ||
13 | size_t temp; | ||
14 | |||
15 | if (!count) | ||
16 | return xs; | ||
17 | c &= 0xff; | ||
18 | c |= c << 8; | ||
19 | c |= c << 16; | ||
20 | if ((long)s & 1) { | ||
21 | char *cs = s; | ||
22 | *cs++ = c; | ||
23 | s = cs; | ||
24 | count--; | ||
25 | } | ||
26 | if (count > 2 && (long)s & 2) { | ||
27 | short *ss = s; | ||
28 | *ss++ = c; | ||
29 | s = ss; | ||
30 | count -= 2; | ||
31 | } | ||
32 | temp = count >> 2; | ||
33 | if (temp) { | ||
34 | long *ls = s; | ||
35 | #if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE) | ||
36 | for (; temp; temp--) | ||
37 | *ls++ = c; | ||
38 | #else | ||
39 | size_t temp1; | ||
40 | asm volatile ( | ||
41 | " movel %1,%2\n" | ||
42 | " andw #7,%2\n" | ||
43 | " lsrl #3,%1\n" | ||
44 | " negw %2\n" | ||
45 | " jmp %%pc@(2f,%2:w:2)\n" | ||
46 | "1: movel %3,%0@+\n" | ||
47 | " movel %3,%0@+\n" | ||
48 | " movel %3,%0@+\n" | ||
49 | " movel %3,%0@+\n" | ||
50 | " movel %3,%0@+\n" | ||
51 | " movel %3,%0@+\n" | ||
52 | " movel %3,%0@+\n" | ||
53 | " movel %3,%0@+\n" | ||
54 | "2: dbra %1,1b\n" | ||
55 | " clrw %1\n" | ||
56 | " subql #1,%1\n" | ||
57 | " jpl 1b" | ||
58 | : "=a" (ls), "=d" (temp), "=&d" (temp1) | ||
59 | : "d" (c), "0" (ls), "1" (temp)); | ||
60 | #endif | ||
61 | s = ls; | ||
62 | } | ||
63 | if (count & 2) { | ||
64 | short *ss = s; | ||
65 | *ss++ = c; | ||
66 | s = ss; | ||
67 | } | ||
68 | if (count & 1) { | ||
69 | char *cs = s; | ||
70 | *cs = c; | ||
71 | } | ||
72 | return xs; | ||
73 | } | ||
74 | EXPORT_SYMBOL(memset); | ||
diff --git a/arch/m68k/lib/modsi3.S b/arch/m68k/lib/modsi3.S new file mode 100644 index 000000000000..ef3849435768 --- /dev/null +++ b/arch/m68k/lib/modsi3.S | |||
@@ -0,0 +1,113 @@ | |||
1 | /* libgcc1 routines for 68000 w/o floating-point hardware. | ||
2 | Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc. | ||
3 | |||
4 | This file is part of GNU CC. | ||
5 | |||
6 | GNU CC is free software; you can redistribute it and/or modify it | ||
7 | under the terms of the GNU General Public License as published by the | ||
8 | Free Software Foundation; either version 2, or (at your option) any | ||
9 | later version. | ||
10 | |||
11 | In addition to the permissions in the GNU General Public License, the | ||
12 | Free Software Foundation gives you unlimited permission to link the | ||
13 | compiled version of this file with other programs, and to distribute | ||
14 | those programs without any restriction coming from the use of this | ||
15 | file. (The General Public License restrictions do apply in other | ||
16 | respects; for example, they cover modification of the file, and | ||
17 | distribution when not linked into another program.) | ||
18 | |||
19 | This file is distributed in the hope that it will be useful, but | ||
20 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
22 | General Public License for more details. | ||
23 | |||
24 | You should have received a copy of the GNU General Public License | ||
25 | along with this program; see the file COPYING. If not, write to | ||
26 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
27 | Boston, MA 02111-1307, USA. */ | ||
28 | |||
29 | /* As a special exception, if you link this library with files | ||
30 | compiled with GCC to produce an executable, this does not cause | ||
31 | the resulting executable to be covered by the GNU General Public License. | ||
32 | This exception does not however invalidate any other reasons why | ||
33 | the executable file might be covered by the GNU General Public License. */ | ||
34 | |||
35 | /* Use this one for any 680x0; assumes no floating point hardware. | ||
36 | The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk. | ||
37 | Some of this code comes from MINIX, via the folks at ericsson. | ||
38 | D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992 | ||
39 | */ | ||
40 | |||
41 | /* These are predefined by new versions of GNU cpp. */ | ||
42 | |||
43 | #ifndef __USER_LABEL_PREFIX__ | ||
44 | #define __USER_LABEL_PREFIX__ _ | ||
45 | #endif | ||
46 | |||
47 | #ifndef __REGISTER_PREFIX__ | ||
48 | #define __REGISTER_PREFIX__ | ||
49 | #endif | ||
50 | |||
51 | #ifndef __IMMEDIATE_PREFIX__ | ||
52 | #define __IMMEDIATE_PREFIX__ # | ||
53 | #endif | ||
54 | |||
55 | /* ANSI concatenation macros. */ | ||
56 | |||
57 | #define CONCAT1(a, b) CONCAT2(a, b) | ||
58 | #define CONCAT2(a, b) a ## b | ||
59 | |||
60 | /* Use the right prefix for global labels. */ | ||
61 | |||
62 | #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) | ||
63 | |||
64 | /* Use the right prefix for registers. */ | ||
65 | |||
66 | #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) | ||
67 | |||
68 | /* Use the right prefix for immediate values. */ | ||
69 | |||
70 | #define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x) | ||
71 | |||
72 | #define d0 REG (d0) | ||
73 | #define d1 REG (d1) | ||
74 | #define d2 REG (d2) | ||
75 | #define d3 REG (d3) | ||
76 | #define d4 REG (d4) | ||
77 | #define d5 REG (d5) | ||
78 | #define d6 REG (d6) | ||
79 | #define d7 REG (d7) | ||
80 | #define a0 REG (a0) | ||
81 | #define a1 REG (a1) | ||
82 | #define a2 REG (a2) | ||
83 | #define a3 REG (a3) | ||
84 | #define a4 REG (a4) | ||
85 | #define a5 REG (a5) | ||
86 | #define a6 REG (a6) | ||
87 | #define fp REG (fp) | ||
88 | #define sp REG (sp) | ||
89 | |||
90 | .text | ||
91 | .proc | ||
92 | .globl SYM (__modsi3) | ||
93 | SYM (__modsi3): | ||
94 | movel sp@(8), d1 /* d1 = divisor */ | ||
95 | movel sp@(4), d0 /* d0 = dividend */ | ||
96 | movel d1, sp@- | ||
97 | movel d0, sp@- | ||
98 | jbsr SYM (__divsi3) | ||
99 | addql IMM (8), sp | ||
100 | movel sp@(8), d1 /* d1 = divisor */ | ||
101 | #if !(defined(__mcf5200__) || defined(__mcoldfire__)) | ||
102 | movel d1, sp@- | ||
103 | movel d0, sp@- | ||
104 | jbsr SYM (__mulsi3) /* d0 = (a/b)*b */ | ||
105 | addql IMM (8), sp | ||
106 | #else | ||
107 | mulsl d1,d0 | ||
108 | #endif | ||
109 | movel sp@(4), d1 /* d1 = dividend */ | ||
110 | subl d0, d1 /* d1 = a - (a/b)*b */ | ||
111 | movel d1, d0 | ||
112 | rts | ||
113 | |||
diff --git a/arch/m68k/lib/muldi3.c b/arch/m68k/lib/muldi3.c index be4f275649e3..79e928a525d0 100644 --- a/arch/m68k/lib/muldi3.c +++ b/arch/m68k/lib/muldi3.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and | 1 | /* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and |
2 | gcc-2.7.2.3/longlong.h which is: */ | 2 | gcc-2.7.2.3/longlong.h which is: */ |
3 | /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. | 3 | /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. |
4 | 4 | ||
@@ -19,7 +19,39 @@ along with GNU CC; see the file COPYING. If not, write to | |||
19 | the Free Software Foundation, 59 Temple Place - Suite 330, | 19 | the Free Software Foundation, 59 Temple Place - Suite 330, |
20 | Boston, MA 02111-1307, USA. */ | 20 | Boston, MA 02111-1307, USA. */ |
21 | 21 | ||
22 | #define BITS_PER_UNIT 8 | 22 | #if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE) |
23 | |||
24 | #define SI_TYPE_SIZE 32 | ||
25 | #define __BITS4 (SI_TYPE_SIZE / 4) | ||
26 | #define __ll_B (1L << (SI_TYPE_SIZE / 2)) | ||
27 | #define __ll_lowpart(t) ((USItype) (t) % __ll_B) | ||
28 | #define __ll_highpart(t) ((USItype) (t) / __ll_B) | ||
29 | |||
30 | #define umul_ppmm(w1, w0, u, v) \ | ||
31 | do { \ | ||
32 | USItype __x0, __x1, __x2, __x3; \ | ||
33 | USItype __ul, __vl, __uh, __vh; \ | ||
34 | \ | ||
35 | __ul = __ll_lowpart (u); \ | ||
36 | __uh = __ll_highpart (u); \ | ||
37 | __vl = __ll_lowpart (v); \ | ||
38 | __vh = __ll_highpart (v); \ | ||
39 | \ | ||
40 | __x0 = (USItype) __ul * __vl; \ | ||
41 | __x1 = (USItype) __ul * __vh; \ | ||
42 | __x2 = (USItype) __uh * __vl; \ | ||
43 | __x3 = (USItype) __uh * __vh; \ | ||
44 | \ | ||
45 | __x1 += __ll_highpart (__x0);/* this can't give carry */ \ | ||
46 | __x1 += __x2; /* but this indeed can */ \ | ||
47 | if (__x1 < __x2) /* did we get it? */ \ | ||
48 | __x3 += __ll_B; /* yes, add it in the proper pos. */ \ | ||
49 | \ | ||
50 | (w1) = __x3 + __ll_highpart (__x1); \ | ||
51 | (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ | ||
52 | } while (0) | ||
53 | |||
54 | #else | ||
23 | 55 | ||
24 | #define umul_ppmm(w1, w0, u, v) \ | 56 | #define umul_ppmm(w1, w0, u, v) \ |
25 | __asm__ ("mulu%.l %3,%1:%0" \ | 57 | __asm__ ("mulu%.l %3,%1:%0" \ |
@@ -28,12 +60,14 @@ Boston, MA 02111-1307, USA. */ | |||
28 | : "%0" ((USItype)(u)), \ | 60 | : "%0" ((USItype)(u)), \ |
29 | "dmi" ((USItype)(v))) | 61 | "dmi" ((USItype)(v))) |
30 | 62 | ||
63 | #endif | ||
64 | |||
31 | #define __umulsidi3(u, v) \ | 65 | #define __umulsidi3(u, v) \ |
32 | ({DIunion __w; \ | 66 | ({DIunion __w; \ |
33 | umul_ppmm (__w.s.high, __w.s.low, u, v); \ | 67 | umul_ppmm (__w.s.high, __w.s.low, u, v); \ |
34 | __w.ll; }) | 68 | __w.ll; }) |
35 | 69 | ||
36 | typedef int SItype __attribute__ ((mode (SI))); | 70 | typedef int SItype __attribute__ ((mode (SI))); |
37 | typedef unsigned int USItype __attribute__ ((mode (SI))); | 71 | typedef unsigned int USItype __attribute__ ((mode (SI))); |
38 | typedef int DItype __attribute__ ((mode (DI))); | 72 | typedef int DItype __attribute__ ((mode (DI))); |
39 | typedef int word_type __attribute__ ((mode (__word__))); | 73 | typedef int word_type __attribute__ ((mode (__word__))); |
diff --git a/arch/m68k/lib/mulsi3.S b/arch/m68k/lib/mulsi3.S new file mode 100644 index 000000000000..ce29ea37b45f --- /dev/null +++ b/arch/m68k/lib/mulsi3.S | |||
@@ -0,0 +1,110 @@ | |||
1 | /* libgcc1 routines for 68000 w/o floating-point hardware. | ||
2 | Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc. | ||
3 | |||
4 | This file is part of GNU CC. | ||
5 | |||
6 | GNU CC is free software; you can redistribute it and/or modify it | ||
7 | under the terms of the GNU General Public License as published by the | ||
8 | Free Software Foundation; either version 2, or (at your option) any | ||
9 | later version. | ||
10 | |||
11 | In addition to the permissions in the GNU General Public License, the | ||
12 | Free Software Foundation gives you unlimited permission to link the | ||
13 | compiled version of this file with other programs, and to distribute | ||
14 | those programs without any restriction coming from the use of this | ||
15 | file. (The General Public License restrictions do apply in other | ||
16 | respects; for example, they cover modification of the file, and | ||
17 | distribution when not linked into another program.) | ||
18 | |||
19 | This file is distributed in the hope that it will be useful, but | ||
20 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
22 | General Public License for more details. | ||
23 | |||
24 | You should have received a copy of the GNU General Public License | ||
25 | along with this program; see the file COPYING. If not, write to | ||
26 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
27 | Boston, MA 02111-1307, USA. */ | ||
28 | |||
29 | /* As a special exception, if you link this library with files | ||
30 | compiled with GCC to produce an executable, this does not cause | ||
31 | the resulting executable to be covered by the GNU General Public License. | ||
32 | This exception does not however invalidate any other reasons why | ||
33 | the executable file might be covered by the GNU General Public License. */ | ||
34 | |||
35 | /* Use this one for any 680x0; assumes no floating point hardware. | ||
36 | The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk. | ||
37 | Some of this code comes from MINIX, via the folks at ericsson. | ||
38 | D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992 | ||
39 | */ | ||
40 | |||
41 | /* These are predefined by new versions of GNU cpp. */ | ||
42 | |||
43 | #ifndef __USER_LABEL_PREFIX__ | ||
44 | #define __USER_LABEL_PREFIX__ _ | ||
45 | #endif | ||
46 | |||
47 | #ifndef __REGISTER_PREFIX__ | ||
48 | #define __REGISTER_PREFIX__ | ||
49 | #endif | ||
50 | |||
51 | #ifndef __IMMEDIATE_PREFIX__ | ||
52 | #define __IMMEDIATE_PREFIX__ # | ||
53 | #endif | ||
54 | |||
55 | /* ANSI concatenation macros. */ | ||
56 | |||
57 | #define CONCAT1(a, b) CONCAT2(a, b) | ||
58 | #define CONCAT2(a, b) a ## b | ||
59 | |||
60 | /* Use the right prefix for global labels. */ | ||
61 | |||
62 | #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) | ||
63 | |||
64 | /* Use the right prefix for registers. */ | ||
65 | |||
66 | #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) | ||
67 | |||
68 | /* Use the right prefix for immediate values. */ | ||
69 | |||
70 | #define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x) | ||
71 | |||
72 | #define d0 REG (d0) | ||
73 | #define d1 REG (d1) | ||
74 | #define d2 REG (d2) | ||
75 | #define d3 REG (d3) | ||
76 | #define d4 REG (d4) | ||
77 | #define d5 REG (d5) | ||
78 | #define d6 REG (d6) | ||
79 | #define d7 REG (d7) | ||
80 | #define a0 REG (a0) | ||
81 | #define a1 REG (a1) | ||
82 | #define a2 REG (a2) | ||
83 | #define a3 REG (a3) | ||
84 | #define a4 REG (a4) | ||
85 | #define a5 REG (a5) | ||
86 | #define a6 REG (a6) | ||
87 | #define fp REG (fp) | ||
88 | #define sp REG (sp) | ||
89 | |||
90 | .text | ||
91 | .proc | ||
92 | .globl SYM (__mulsi3) | ||
93 | SYM (__mulsi3): | ||
94 | movew sp@(4), d0 /* x0 -> d0 */ | ||
95 | muluw sp@(10), d0 /* x0*y1 */ | ||
96 | movew sp@(6), d1 /* x1 -> d1 */ | ||
97 | muluw sp@(8), d1 /* x1*y0 */ | ||
98 | #if !(defined(__mcf5200__) || defined(__mcoldfire__)) | ||
99 | addw d1, d0 | ||
100 | #else | ||
101 | addl d1, d0 | ||
102 | #endif | ||
103 | swap d0 | ||
104 | clrw d0 | ||
105 | movew sp@(6), d1 /* x1 -> d1 */ | ||
106 | muluw sp@(10), d1 /* x1*y1 */ | ||
107 | addl d1, d0 | ||
108 | |||
109 | rts | ||
110 | |||
diff --git a/arch/m68k/lib/string.c b/arch/m68k/lib/string.c index 4253f870e54f..b9a57abfad08 100644 --- a/arch/m68k/lib/string.c +++ b/arch/m68k/lib/string.c | |||
@@ -20,237 +20,3 @@ char *strcat(char *dest, const char *src) | |||
20 | return __kernel_strcpy(dest + __kernel_strlen(dest), src); | 20 | return __kernel_strcpy(dest + __kernel_strlen(dest), src); |
21 | } | 21 | } |
22 | EXPORT_SYMBOL(strcat); | 22 | EXPORT_SYMBOL(strcat); |
23 | |||
24 | void *memset(void *s, int c, size_t count) | ||
25 | { | ||
26 | void *xs = s; | ||
27 | size_t temp, temp1; | ||
28 | |||
29 | if (!count) | ||
30 | return xs; | ||
31 | c &= 0xff; | ||
32 | c |= c << 8; | ||
33 | c |= c << 16; | ||
34 | if ((long)s & 1) { | ||
35 | char *cs = s; | ||
36 | *cs++ = c; | ||
37 | s = cs; | ||
38 | count--; | ||
39 | } | ||
40 | if (count > 2 && (long)s & 2) { | ||
41 | short *ss = s; | ||
42 | *ss++ = c; | ||
43 | s = ss; | ||
44 | count -= 2; | ||
45 | } | ||
46 | temp = count >> 2; | ||
47 | if (temp) { | ||
48 | long *ls = s; | ||
49 | |||
50 | asm volatile ( | ||
51 | " movel %1,%2\n" | ||
52 | " andw #7,%2\n" | ||
53 | " lsrl #3,%1\n" | ||
54 | " negw %2\n" | ||
55 | " jmp %%pc@(2f,%2:w:2)\n" | ||
56 | "1: movel %3,%0@+\n" | ||
57 | " movel %3,%0@+\n" | ||
58 | " movel %3,%0@+\n" | ||
59 | " movel %3,%0@+\n" | ||
60 | " movel %3,%0@+\n" | ||
61 | " movel %3,%0@+\n" | ||
62 | " movel %3,%0@+\n" | ||
63 | " movel %3,%0@+\n" | ||
64 | "2: dbra %1,1b\n" | ||
65 | " clrw %1\n" | ||
66 | " subql #1,%1\n" | ||
67 | " jpl 1b" | ||
68 | : "=a" (ls), "=d" (temp), "=&d" (temp1) | ||
69 | : "d" (c), "0" (ls), "1" (temp)); | ||
70 | s = ls; | ||
71 | } | ||
72 | if (count & 2) { | ||
73 | short *ss = s; | ||
74 | *ss++ = c; | ||
75 | s = ss; | ||
76 | } | ||
77 | if (count & 1) { | ||
78 | char *cs = s; | ||
79 | *cs = c; | ||
80 | } | ||
81 | return xs; | ||
82 | } | ||
83 | EXPORT_SYMBOL(memset); | ||
84 | |||
85 | void *memcpy(void *to, const void *from, size_t n) | ||
86 | { | ||
87 | void *xto = to; | ||
88 | size_t temp, temp1; | ||
89 | |||
90 | if (!n) | ||
91 | return xto; | ||
92 | if ((long)to & 1) { | ||
93 | char *cto = to; | ||
94 | const char *cfrom = from; | ||
95 | *cto++ = *cfrom++; | ||
96 | to = cto; | ||
97 | from = cfrom; | ||
98 | n--; | ||
99 | } | ||
100 | if (n > 2 && (long)to & 2) { | ||
101 | short *sto = to; | ||
102 | const short *sfrom = from; | ||
103 | *sto++ = *sfrom++; | ||
104 | to = sto; | ||
105 | from = sfrom; | ||
106 | n -= 2; | ||
107 | } | ||
108 | temp = n >> 2; | ||
109 | if (temp) { | ||
110 | long *lto = to; | ||
111 | const long *lfrom = from; | ||
112 | |||
113 | asm volatile ( | ||
114 | " movel %2,%3\n" | ||
115 | " andw #7,%3\n" | ||
116 | " lsrl #3,%2\n" | ||
117 | " negw %3\n" | ||
118 | " jmp %%pc@(1f,%3:w:2)\n" | ||
119 | "4: movel %0@+,%1@+\n" | ||
120 | " movel %0@+,%1@+\n" | ||
121 | " movel %0@+,%1@+\n" | ||
122 | " movel %0@+,%1@+\n" | ||
123 | " movel %0@+,%1@+\n" | ||
124 | " movel %0@+,%1@+\n" | ||
125 | " movel %0@+,%1@+\n" | ||
126 | " movel %0@+,%1@+\n" | ||
127 | "1: dbra %2,4b\n" | ||
128 | " clrw %2\n" | ||
129 | " subql #1,%2\n" | ||
130 | " jpl 4b" | ||
131 | : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1) | ||
132 | : "0" (lfrom), "1" (lto), "2" (temp)); | ||
133 | to = lto; | ||
134 | from = lfrom; | ||
135 | } | ||
136 | if (n & 2) { | ||
137 | short *sto = to; | ||
138 | const short *sfrom = from; | ||
139 | *sto++ = *sfrom++; | ||
140 | to = sto; | ||
141 | from = sfrom; | ||
142 | } | ||
143 | if (n & 1) { | ||
144 | char *cto = to; | ||
145 | const char *cfrom = from; | ||
146 | *cto = *cfrom; | ||
147 | } | ||
148 | return xto; | ||
149 | } | ||
150 | EXPORT_SYMBOL(memcpy); | ||
151 | |||
152 | void *memmove(void *dest, const void *src, size_t n) | ||
153 | { | ||
154 | void *xdest = dest; | ||
155 | size_t temp; | ||
156 | |||
157 | if (!n) | ||
158 | return xdest; | ||
159 | |||
160 | if (dest < src) { | ||
161 | if ((long)dest & 1) { | ||
162 | char *cdest = dest; | ||
163 | const char *csrc = src; | ||
164 | *cdest++ = *csrc++; | ||
165 | dest = cdest; | ||
166 | src = csrc; | ||
167 | n--; | ||
168 | } | ||
169 | if (n > 2 && (long)dest & 2) { | ||
170 | short *sdest = dest; | ||
171 | const short *ssrc = src; | ||
172 | *sdest++ = *ssrc++; | ||
173 | dest = sdest; | ||
174 | src = ssrc; | ||
175 | n -= 2; | ||
176 | } | ||
177 | temp = n >> 2; | ||
178 | if (temp) { | ||
179 | long *ldest = dest; | ||
180 | const long *lsrc = src; | ||
181 | temp--; | ||
182 | do | ||
183 | *ldest++ = *lsrc++; | ||
184 | while (temp--); | ||
185 | dest = ldest; | ||
186 | src = lsrc; | ||
187 | } | ||
188 | if (n & 2) { | ||
189 | short *sdest = dest; | ||
190 | const short *ssrc = src; | ||
191 | *sdest++ = *ssrc++; | ||
192 | dest = sdest; | ||
193 | src = ssrc; | ||
194 | } | ||
195 | if (n & 1) { | ||
196 | char *cdest = dest; | ||
197 | const char *csrc = src; | ||
198 | *cdest = *csrc; | ||
199 | } | ||
200 | } else { | ||
201 | dest = (char *)dest + n; | ||
202 | src = (const char *)src + n; | ||
203 | if ((long)dest & 1) { | ||
204 | char *cdest = dest; | ||
205 | const char *csrc = src; | ||
206 | *--cdest = *--csrc; | ||
207 | dest = cdest; | ||
208 | src = csrc; | ||
209 | n--; | ||
210 | } | ||
211 | if (n > 2 && (long)dest & 2) { | ||
212 | short *sdest = dest; | ||
213 | const short *ssrc = src; | ||
214 | *--sdest = *--ssrc; | ||
215 | dest = sdest; | ||
216 | src = ssrc; | ||
217 | n -= 2; | ||
218 | } | ||
219 | temp = n >> 2; | ||
220 | if (temp) { | ||
221 | long *ldest = dest; | ||
222 | const long *lsrc = src; | ||
223 | temp--; | ||
224 | do | ||
225 | *--ldest = *--lsrc; | ||
226 | while (temp--); | ||
227 | dest = ldest; | ||
228 | src = lsrc; | ||
229 | } | ||
230 | if (n & 2) { | ||
231 | short *sdest = dest; | ||
232 | const short *ssrc = src; | ||
233 | *--sdest = *--ssrc; | ||
234 | dest = sdest; | ||
235 | src = ssrc; | ||
236 | } | ||
237 | if (n & 1) { | ||
238 | char *cdest = dest; | ||
239 | const char *csrc = src; | ||
240 | *--cdest = *--csrc; | ||
241 | } | ||
242 | } | ||
243 | return xdest; | ||
244 | } | ||
245 | EXPORT_SYMBOL(memmove); | ||
246 | |||
247 | int memcmp(const void *cs, const void *ct, size_t count) | ||
248 | { | ||
249 | const unsigned char *su1, *su2; | ||
250 | |||
251 | for (su1 = cs, su2 = ct; count > 0; ++su1, ++su2, count--) | ||
252 | if (*su1 != *su2) | ||
253 | return *su1 < *su2 ? -1 : +1; | ||
254 | return 0; | ||
255 | } | ||
256 | EXPORT_SYMBOL(memcmp); | ||
diff --git a/arch/m68k/lib/udivsi3.S b/arch/m68k/lib/udivsi3.S new file mode 100644 index 000000000000..c424c4a1f0a3 --- /dev/null +++ b/arch/m68k/lib/udivsi3.S | |||
@@ -0,0 +1,162 @@ | |||
1 | /* libgcc1 routines for 68000 w/o floating-point hardware. | ||
2 | Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc. | ||
3 | |||
4 | This file is part of GNU CC. | ||
5 | |||
6 | GNU CC is free software; you can redistribute it and/or modify it | ||
7 | under the terms of the GNU General Public License as published by the | ||
8 | Free Software Foundation; either version 2, or (at your option) any | ||
9 | later version. | ||
10 | |||
11 | In addition to the permissions in the GNU General Public License, the | ||
12 | Free Software Foundation gives you unlimited permission to link the | ||
13 | compiled version of this file with other programs, and to distribute | ||
14 | those programs without any restriction coming from the use of this | ||
15 | file. (The General Public License restrictions do apply in other | ||
16 | respects; for example, they cover modification of the file, and | ||
17 | distribution when not linked into another program.) | ||
18 | |||
19 | This file is distributed in the hope that it will be useful, but | ||
20 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
22 | General Public License for more details. | ||
23 | |||
24 | You should have received a copy of the GNU General Public License | ||
25 | along with this program; see the file COPYING. If not, write to | ||
26 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
27 | Boston, MA 02111-1307, USA. */ | ||
28 | |||
29 | /* As a special exception, if you link this library with files | ||
30 | compiled with GCC to produce an executable, this does not cause | ||
31 | the resulting executable to be covered by the GNU General Public License. | ||
32 | This exception does not however invalidate any other reasons why | ||
33 | the executable file might be covered by the GNU General Public License. */ | ||
34 | |||
35 | /* Use this one for any 680x0; assumes no floating point hardware. | ||
36 | The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk. | ||
37 | Some of this code comes from MINIX, via the folks at ericsson. | ||
38 | D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992 | ||
39 | */ | ||
40 | |||
41 | /* These are predefined by new versions of GNU cpp. */ | ||
42 | |||
43 | #ifndef __USER_LABEL_PREFIX__ | ||
44 | #define __USER_LABEL_PREFIX__ _ | ||
45 | #endif | ||
46 | |||
47 | #ifndef __REGISTER_PREFIX__ | ||
48 | #define __REGISTER_PREFIX__ | ||
49 | #endif | ||
50 | |||
51 | #ifndef __IMMEDIATE_PREFIX__ | ||
52 | #define __IMMEDIATE_PREFIX__ # | ||
53 | #endif | ||
54 | |||
55 | /* ANSI concatenation macros. */ | ||
56 | |||
57 | #define CONCAT1(a, b) CONCAT2(a, b) | ||
58 | #define CONCAT2(a, b) a ## b | ||
59 | |||
60 | /* Use the right prefix for global labels. */ | ||
61 | |||
62 | #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) | ||
63 | |||
64 | /* Use the right prefix for registers. */ | ||
65 | |||
66 | #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) | ||
67 | |||
68 | /* Use the right prefix for immediate values. */ | ||
69 | |||
70 | #define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x) | ||
71 | |||
72 | #define d0 REG (d0) | ||
73 | #define d1 REG (d1) | ||
74 | #define d2 REG (d2) | ||
75 | #define d3 REG (d3) | ||
76 | #define d4 REG (d4) | ||
77 | #define d5 REG (d5) | ||
78 | #define d6 REG (d6) | ||
79 | #define d7 REG (d7) | ||
80 | #define a0 REG (a0) | ||
81 | #define a1 REG (a1) | ||
82 | #define a2 REG (a2) | ||
83 | #define a3 REG (a3) | ||
84 | #define a4 REG (a4) | ||
85 | #define a5 REG (a5) | ||
86 | #define a6 REG (a6) | ||
87 | #define fp REG (fp) | ||
88 | #define sp REG (sp) | ||
89 | |||
90 | .text | ||
91 | .proc | ||
92 | .globl SYM (__udivsi3) | ||
93 | SYM (__udivsi3): | ||
94 | #if !(defined(__mcf5200__) || defined(__mcoldfire__)) | ||
95 | movel d2, sp@- | ||
96 | movel sp@(12), d1 /* d1 = divisor */ | ||
97 | movel sp@(8), d0 /* d0 = dividend */ | ||
98 | |||
99 | cmpl IMM (0x10000), d1 /* divisor >= 2 ^ 16 ? */ | ||
100 | jcc L3 /* then try next algorithm */ | ||
101 | movel d0, d2 | ||
102 | clrw d2 | ||
103 | swap d2 | ||
104 | divu d1, d2 /* high quotient in lower word */ | ||
105 | movew d2, d0 /* save high quotient */ | ||
106 | swap d0 | ||
107 | movew sp@(10), d2 /* get low dividend + high rest */ | ||
108 | divu d1, d2 /* low quotient */ | ||
109 | movew d2, d0 | ||
110 | jra L6 | ||
111 | |||
112 | L3: movel d1, d2 /* use d2 as divisor backup */ | ||
113 | L4: lsrl IMM (1), d1 /* shift divisor */ | ||
114 | lsrl IMM (1), d0 /* shift dividend */ | ||
115 | cmpl IMM (0x10000), d1 /* still divisor >= 2 ^ 16 ? */ | ||
116 | jcc L4 | ||
117 | divu d1, d0 /* now we have 16 bit divisor */ | ||
118 | andl IMM (0xffff), d0 /* mask out divisor, ignore remainder */ | ||
119 | |||
120 | /* Multiply the 16 bit tentative quotient with the 32 bit divisor. Because of | ||
121 | the operand ranges, this might give a 33 bit product. If this product is | ||
122 | greater than the dividend, the tentative quotient was too large. */ | ||
123 | movel d2, d1 | ||
124 | mulu d0, d1 /* low part, 32 bits */ | ||
125 | swap d2 | ||
126 | mulu d0, d2 /* high part, at most 17 bits */ | ||
127 | swap d2 /* align high part with low part */ | ||
128 | tstw d2 /* high part 17 bits? */ | ||
129 | jne L5 /* if 17 bits, quotient was too large */ | ||
130 | addl d2, d1 /* add parts */ | ||
131 | jcs L5 /* if sum is 33 bits, quotient was too large */ | ||
132 | cmpl sp@(8), d1 /* compare the sum with the dividend */ | ||
133 | jls L6 /* if sum > dividend, quotient was too large */ | ||
134 | L5: subql IMM (1), d0 /* adjust quotient */ | ||
135 | |||
136 | L6: movel sp@+, d2 | ||
137 | rts | ||
138 | |||
139 | #else /* __mcf5200__ || __mcoldfire__ */ | ||
140 | |||
141 | /* Coldfire implementation of non-restoring division algorithm from | ||
142 | Hennessy & Patterson, Appendix A. */ | ||
143 | link a6,IMM (-12) | ||
144 | moveml d2-d4,sp@ | ||
145 | movel a6@(8),d0 | ||
146 | movel a6@(12),d1 | ||
147 | clrl d2 | clear p | ||
148 | moveq IMM (31),d4 | ||
149 | L1: addl d0,d0 | shift reg pair (p,a) one bit left | ||
150 | addxl d2,d2 | ||
151 | movl d2,d3 | subtract b from p, store in tmp. | ||
152 | subl d1,d3 | ||
153 | jcs L2 | if no carry, | ||
154 | bset IMM (0),d0 | set the low order bit of a to 1, | ||
155 | movl d3,d2 | and store tmp in p. | ||
156 | L2: subql IMM (1),d4 | ||
157 | jcc L1 | ||
158 | moveml sp@,d2-d4 | restore data registers | ||
159 | unlk a6 | and return | ||
160 | rts | ||
161 | #endif /* __mcf5200__ || __mcoldfire__ */ | ||
162 | |||
diff --git a/arch/m68k/lib/umodsi3.S b/arch/m68k/lib/umodsi3.S new file mode 100644 index 000000000000..5def5f626478 --- /dev/null +++ b/arch/m68k/lib/umodsi3.S | |||
@@ -0,0 +1,113 @@ | |||
1 | /* libgcc1 routines for 68000 w/o floating-point hardware. | ||
2 | Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc. | ||
3 | |||
4 | This file is part of GNU CC. | ||
5 | |||
6 | GNU CC is free software; you can redistribute it and/or modify it | ||
7 | under the terms of the GNU General Public License as published by the | ||
8 | Free Software Foundation; either version 2, or (at your option) any | ||
9 | later version. | ||
10 | |||
11 | In addition to the permissions in the GNU General Public License, the | ||
12 | Free Software Foundation gives you unlimited permission to link the | ||
13 | compiled version of this file with other programs, and to distribute | ||
14 | those programs without any restriction coming from the use of this | ||
15 | file. (The General Public License restrictions do apply in other | ||
16 | respects; for example, they cover modification of the file, and | ||
17 | distribution when not linked into another program.) | ||
18 | |||
19 | This file is distributed in the hope that it will be useful, but | ||
20 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
22 | General Public License for more details. | ||
23 | |||
24 | You should have received a copy of the GNU General Public License | ||
25 | along with this program; see the file COPYING. If not, write to | ||
26 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
27 | Boston, MA 02111-1307, USA. */ | ||
28 | |||
29 | /* As a special exception, if you link this library with files | ||
30 | compiled with GCC to produce an executable, this does not cause | ||
31 | the resulting executable to be covered by the GNU General Public License. | ||
32 | This exception does not however invalidate any other reasons why | ||
33 | the executable file might be covered by the GNU General Public License. */ | ||
34 | |||
35 | /* Use this one for any 680x0; assumes no floating point hardware. | ||
36 | The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk. | ||
37 | Some of this code comes from MINIX, via the folks at ericsson. | ||
38 | D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992 | ||
39 | */ | ||
40 | |||
41 | /* These are predefined by new versions of GNU cpp. */ | ||
42 | |||
43 | #ifndef __USER_LABEL_PREFIX__ | ||
44 | #define __USER_LABEL_PREFIX__ _ | ||
45 | #endif | ||
46 | |||
47 | #ifndef __REGISTER_PREFIX__ | ||
48 | #define __REGISTER_PREFIX__ | ||
49 | #endif | ||
50 | |||
51 | #ifndef __IMMEDIATE_PREFIX__ | ||
52 | #define __IMMEDIATE_PREFIX__ # | ||
53 | #endif | ||
54 | |||
55 | /* ANSI concatenation macros. */ | ||
56 | |||
57 | #define CONCAT1(a, b) CONCAT2(a, b) | ||
58 | #define CONCAT2(a, b) a ## b | ||
59 | |||
60 | /* Use the right prefix for global labels. */ | ||
61 | |||
62 | #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) | ||
63 | |||
64 | /* Use the right prefix for registers. */ | ||
65 | |||
66 | #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) | ||
67 | |||
68 | /* Use the right prefix for immediate values. */ | ||
69 | |||
70 | #define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x) | ||
71 | |||
72 | #define d0 REG (d0) | ||
73 | #define d1 REG (d1) | ||
74 | #define d2 REG (d2) | ||
75 | #define d3 REG (d3) | ||
76 | #define d4 REG (d4) | ||
77 | #define d5 REG (d5) | ||
78 | #define d6 REG (d6) | ||
79 | #define d7 REG (d7) | ||
80 | #define a0 REG (a0) | ||
81 | #define a1 REG (a1) | ||
82 | #define a2 REG (a2) | ||
83 | #define a3 REG (a3) | ||
84 | #define a4 REG (a4) | ||
85 | #define a5 REG (a5) | ||
86 | #define a6 REG (a6) | ||
87 | #define fp REG (fp) | ||
88 | #define sp REG (sp) | ||
89 | |||
90 | .text | ||
91 | .proc | ||
92 | .globl SYM (__umodsi3) | ||
93 | SYM (__umodsi3): | ||
94 | movel sp@(8), d1 /* d1 = divisor */ | ||
95 | movel sp@(4), d0 /* d0 = dividend */ | ||
96 | movel d1, sp@- | ||
97 | movel d0, sp@- | ||
98 | jbsr SYM (__udivsi3) | ||
99 | addql IMM (8), sp | ||
100 | movel sp@(8), d1 /* d1 = divisor */ | ||
101 | #if !(defined(__mcf5200__) || defined(__mcoldfire__)) | ||
102 | movel d1, sp@- | ||
103 | movel d0, sp@- | ||
104 | jbsr SYM (__mulsi3) /* d0 = (a/b)*b */ | ||
105 | addql IMM (8), sp | ||
106 | #else | ||
107 | mulsl d1,d0 | ||
108 | #endif | ||
109 | movel sp@(4), d1 /* d1 = dividend */ | ||
110 | subl d0, d1 /* d1 = a - (a/b)*b */ | ||
111 | movel d1, d0 | ||
112 | rts | ||
113 | |||