diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/m68knommu/lib |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/m68knommu/lib')
-rw-r--r-- | arch/m68knommu/lib/Makefile | 7 | ||||
-rw-r--r-- | arch/m68knommu/lib/ashldi3.c | 62 | ||||
-rw-r--r-- | arch/m68knommu/lib/ashrdi3.c | 63 | ||||
-rw-r--r-- | arch/m68knommu/lib/checksum.c | 160 | ||||
-rw-r--r-- | arch/m68knommu/lib/delay.c | 21 | ||||
-rw-r--r-- | arch/m68knommu/lib/divsi3.S | 125 | ||||
-rw-r--r-- | arch/m68knommu/lib/lshrdi3.c | 62 | ||||
-rw-r--r-- | arch/m68knommu/lib/memcpy.c | 63 | ||||
-rw-r--r-- | arch/m68knommu/lib/memset.c | 47 | ||||
-rw-r--r-- | arch/m68knommu/lib/modsi3.S | 113 | ||||
-rw-r--r-- | arch/m68knommu/lib/muldi3.c | 86 | ||||
-rw-r--r-- | arch/m68knommu/lib/mulsi3.S | 110 | ||||
-rw-r--r-- | arch/m68knommu/lib/semaphore.S | 67 | ||||
-rw-r--r-- | arch/m68knommu/lib/udivsi3.S | 162 | ||||
-rw-r--r-- | arch/m68knommu/lib/umodsi3.S | 113 |
15 files changed, 1261 insertions, 0 deletions
diff --git a/arch/m68knommu/lib/Makefile b/arch/m68knommu/lib/Makefile new file mode 100644 index 000000000000..e051a7913987 --- /dev/null +++ b/arch/m68knommu/lib/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Makefile for m68knommu specific library files.. | ||
3 | # | ||
4 | |||
5 | lib-y := ashldi3.o ashrdi3.o lshrdi3.o \ | ||
6 | muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ | ||
7 | checksum.o semaphore.o memcpy.o memset.o delay.o | ||
diff --git a/arch/m68knommu/lib/ashldi3.c b/arch/m68knommu/lib/ashldi3.c new file mode 100644 index 000000000000..008403eb8ce2 --- /dev/null +++ b/arch/m68knommu/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 | |||
4 | This file is part of GNU CC. | ||
5 | |||
6 | GNU CC is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2, or (at your option) | ||
9 | any later version. | ||
10 | |||
11 | GNU CC is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with GNU CC; see the file COPYING. If not, write to | ||
18 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
19 | Boston, MA 02111-1307, USA. */ | ||
20 | |||
21 | #define BITS_PER_UNIT 8 | ||
22 | |||
23 | typedef int SItype __attribute__ ((mode (SI))); | ||
24 | typedef unsigned int USItype __attribute__ ((mode (SI))); | ||
25 | typedef int DItype __attribute__ ((mode (DI))); | ||
26 | typedef int word_type __attribute__ ((mode (__word__))); | ||
27 | |||
28 | struct DIstruct {SItype high, low;}; | ||
29 | |||
30 | typedef union | ||
31 | { | ||
32 | struct DIstruct s; | ||
33 | DItype ll; | ||
34 | } DIunion; | ||
35 | |||
36 | DItype | ||
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/m68knommu/lib/ashrdi3.c b/arch/m68knommu/lib/ashrdi3.c new file mode 100644 index 000000000000..78efb65e315a --- /dev/null +++ b/arch/m68knommu/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 | |||
4 | This file is part of GNU CC. | ||
5 | |||
6 | GNU CC is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2, or (at your option) | ||
9 | any later version. | ||
10 | |||
11 | GNU CC is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with GNU CC; see the file COPYING. If not, write to | ||
18 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
19 | Boston, MA 02111-1307, USA. */ | ||
20 | |||
21 | #define BITS_PER_UNIT 8 | ||
22 | |||
23 | typedef int SItype __attribute__ ((mode (SI))); | ||
24 | typedef unsigned int USItype __attribute__ ((mode (SI))); | ||
25 | typedef int DItype __attribute__ ((mode (DI))); | ||
26 | typedef int word_type __attribute__ ((mode (__word__))); | ||
27 | |||
28 | struct DIstruct {SItype high, low;}; | ||
29 | |||
30 | typedef union | ||
31 | { | ||
32 | struct DIstruct s; | ||
33 | DItype ll; | ||
34 | } DIunion; | ||
35 | |||
36 | DItype | ||
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/m68knommu/lib/checksum.c b/arch/m68knommu/lib/checksum.c new file mode 100644 index 000000000000..7bec6fdee34b --- /dev/null +++ b/arch/m68knommu/lib/checksum.c | |||
@@ -0,0 +1,160 @@ | |||
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 | /* | ||
96 | * This is a version of ip_compute_csum() optimized for IP headers, | ||
97 | * which always checksum on 4 octet boundaries. | ||
98 | */ | ||
99 | unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl) | ||
100 | { | ||
101 | return ~do_csum(iph,ihl*4); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * computes the checksum of a memory block at buff, length len, | ||
106 | * and adds in "sum" (32-bit) | ||
107 | * | ||
108 | * returns a 32-bit number suitable for feeding into itself | ||
109 | * or csum_tcpudp_magic | ||
110 | * | ||
111 | * this function must be called with even lengths, except | ||
112 | * for the last fragment, which may be odd | ||
113 | * | ||
114 | * it's best to have buff aligned on a 32-bit boundary | ||
115 | */ | ||
116 | unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) | ||
117 | { | ||
118 | unsigned int result = do_csum(buff, len); | ||
119 | |||
120 | /* add in old sum, and carry.. */ | ||
121 | result += sum; | ||
122 | if (sum > result) | ||
123 | result += 1; | ||
124 | return result; | ||
125 | } | ||
126 | |||
127 | EXPORT_SYMBOL(csum_partial); | ||
128 | |||
129 | /* | ||
130 | * this routine is used for miscellaneous IP-like checksums, mainly | ||
131 | * in icmp.c | ||
132 | */ | ||
133 | unsigned short ip_compute_csum(const unsigned char * buff, int len) | ||
134 | { | ||
135 | return ~do_csum(buff,len); | ||
136 | } | ||
137 | |||
138 | /* | ||
139 | * copy from fs while checksumming, otherwise like csum_partial | ||
140 | */ | ||
141 | |||
142 | unsigned int | ||
143 | csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, | ||
144 | int len, int sum, int *csum_err) | ||
145 | { | ||
146 | if (csum_err) *csum_err = 0; | ||
147 | memcpy(dst, src, len); | ||
148 | return csum_partial(dst, len, sum); | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | * copy from ds while checksumming, otherwise like csum_partial | ||
153 | */ | ||
154 | |||
155 | unsigned int | ||
156 | csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum) | ||
157 | { | ||
158 | memcpy(dst, src, len); | ||
159 | return csum_partial(dst, len, sum); | ||
160 | } | ||
diff --git a/arch/m68knommu/lib/delay.c b/arch/m68knommu/lib/delay.c new file mode 100644 index 000000000000..5bd5472d38a0 --- /dev/null +++ b/arch/m68knommu/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/m68knommu/lib/divsi3.S b/arch/m68knommu/lib/divsi3.S new file mode 100644 index 000000000000..ec307b61991e --- /dev/null +++ b/arch/m68knommu/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/m68knommu/lib/lshrdi3.c b/arch/m68knommu/lib/lshrdi3.c new file mode 100644 index 000000000000..93b1cb6fdee8 --- /dev/null +++ b/arch/m68knommu/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 | |||
4 | This file is part of GNU CC. | ||
5 | |||
6 | GNU CC is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2, or (at your option) | ||
9 | any later version. | ||
10 | |||
11 | GNU CC is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with GNU CC; see the file COPYING. If not, write to | ||
18 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
19 | Boston, MA 02111-1307, USA. */ | ||
20 | |||
21 | #define BITS_PER_UNIT 8 | ||
22 | |||
23 | typedef int SItype __attribute__ ((mode (SI))); | ||
24 | typedef unsigned int USItype __attribute__ ((mode (SI))); | ||
25 | typedef int DItype __attribute__ ((mode (DI))); | ||
26 | typedef int word_type __attribute__ ((mode (__word__))); | ||
27 | |||
28 | struct DIstruct {SItype high, low;}; | ||
29 | |||
30 | typedef union | ||
31 | { | ||
32 | struct DIstruct s; | ||
33 | DItype ll; | ||
34 | } DIunion; | ||
35 | |||
36 | DItype | ||
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/m68knommu/lib/memcpy.c b/arch/m68knommu/lib/memcpy.c new file mode 100644 index 000000000000..0d5577569e4c --- /dev/null +++ b/arch/m68knommu/lib/memcpy.c | |||
@@ -0,0 +1,63 @@ | |||
1 | |||
2 | #include <linux/types.h> | ||
3 | #include <linux/autoconf.h> | ||
4 | |||
5 | void * memcpy(void * to, const void * from, size_t n) | ||
6 | { | ||
7 | #ifdef CONFIG_COLDFIRE | ||
8 | void *xto = to; | ||
9 | size_t temp; | ||
10 | |||
11 | if (!n) | ||
12 | return xto; | ||
13 | if ((long) to & 1) | ||
14 | { | ||
15 | char *cto = to; | ||
16 | const char *cfrom = from; | ||
17 | *cto++ = *cfrom++; | ||
18 | to = cto; | ||
19 | from = cfrom; | ||
20 | n--; | ||
21 | } | ||
22 | if (n > 2 && (long) to & 2) | ||
23 | { | ||
24 | short *sto = to; | ||
25 | const short *sfrom = from; | ||
26 | *sto++ = *sfrom++; | ||
27 | to = sto; | ||
28 | from = sfrom; | ||
29 | n -= 2; | ||
30 | } | ||
31 | temp = n >> 2; | ||
32 | if (temp) | ||
33 | { | ||
34 | long *lto = to; | ||
35 | const long *lfrom = from; | ||
36 | for (; temp; temp--) | ||
37 | *lto++ = *lfrom++; | ||
38 | to = lto; | ||
39 | from = lfrom; | ||
40 | } | ||
41 | if (n & 2) | ||
42 | { | ||
43 | short *sto = to; | ||
44 | const short *sfrom = from; | ||
45 | *sto++ = *sfrom++; | ||
46 | to = sto; | ||
47 | from = sfrom; | ||
48 | } | ||
49 | if (n & 1) | ||
50 | { | ||
51 | char *cto = to; | ||
52 | const char *cfrom = from; | ||
53 | *cto = *cfrom; | ||
54 | } | ||
55 | return xto; | ||
56 | #else | ||
57 | const char *c_from = from; | ||
58 | char *c_to = to; | ||
59 | while (n-- > 0) | ||
60 | *c_to++ = *c_from++; | ||
61 | return((void *) to); | ||
62 | #endif | ||
63 | } | ||
diff --git a/arch/m68knommu/lib/memset.c b/arch/m68knommu/lib/memset.c new file mode 100644 index 000000000000..1389bf455633 --- /dev/null +++ b/arch/m68knommu/lib/memset.c | |||
@@ -0,0 +1,47 @@ | |||
1 | #include <linux/types.h> | ||
2 | |||
3 | void * memset(void * s, int c, size_t count) | ||
4 | { | ||
5 | void *xs = s; | ||
6 | size_t temp; | ||
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 | for (; temp; temp--) | ||
32 | *ls++ = c; | ||
33 | s = ls; | ||
34 | } | ||
35 | if (count & 2) | ||
36 | { | ||
37 | short *ss = s; | ||
38 | *ss++ = c; | ||
39 | s = ss; | ||
40 | } | ||
41 | if (count & 1) | ||
42 | { | ||
43 | char *cs = s; | ||
44 | *cs = c; | ||
45 | } | ||
46 | return xs; | ||
47 | } | ||
diff --git a/arch/m68knommu/lib/modsi3.S b/arch/m68knommu/lib/modsi3.S new file mode 100644 index 000000000000..ef3849435768 --- /dev/null +++ b/arch/m68knommu/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/m68knommu/lib/muldi3.c b/arch/m68knommu/lib/muldi3.c new file mode 100644 index 000000000000..34af72c30303 --- /dev/null +++ b/arch/m68knommu/lib/muldi3.c | |||
@@ -0,0 +1,86 @@ | |||
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 | |||
5 | This file is part of GNU CC. | ||
6 | |||
7 | GNU CC is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2, or (at your option) | ||
10 | any later version. | ||
11 | |||
12 | GNU CC is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with GNU CC; see the file COPYING. If not, write to | ||
19 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
20 | Boston, MA 02111-1307, USA. */ | ||
21 | |||
22 | #define BITS_PER_UNIT 8 | ||
23 | #define SI_TYPE_SIZE 32 | ||
24 | |||
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 | #define __umulsidi3(u, v) \ | ||
55 | ({DIunion __w; \ | ||
56 | umul_ppmm (__w.s.high, __w.s.low, u, v); \ | ||
57 | __w.ll; }) | ||
58 | |||
59 | typedef int SItype __attribute__ ((mode (SI))); | ||
60 | typedef unsigned int USItype __attribute__ ((mode (SI))); | ||
61 | typedef int DItype __attribute__ ((mode (DI))); | ||
62 | typedef int word_type __attribute__ ((mode (__word__))); | ||
63 | |||
64 | struct DIstruct {SItype high, low;}; | ||
65 | |||
66 | typedef union | ||
67 | { | ||
68 | struct DIstruct s; | ||
69 | DItype ll; | ||
70 | } DIunion; | ||
71 | |||
72 | DItype | ||
73 | __muldi3 (DItype u, DItype v) | ||
74 | { | ||
75 | DIunion w; | ||
76 | DIunion uu, vv; | ||
77 | |||
78 | uu.ll = u, | ||
79 | vv.ll = v; | ||
80 | |||
81 | w.ll = __umulsidi3 (uu.s.low, vv.s.low); | ||
82 | w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high | ||
83 | + (USItype) uu.s.high * (USItype) vv.s.low); | ||
84 | |||
85 | return w.ll; | ||
86 | } | ||
diff --git a/arch/m68knommu/lib/mulsi3.S b/arch/m68knommu/lib/mulsi3.S new file mode 100644 index 000000000000..ce29ea37b45f --- /dev/null +++ b/arch/m68knommu/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/m68knommu/lib/semaphore.S b/arch/m68knommu/lib/semaphore.S new file mode 100644 index 000000000000..76765362fea6 --- /dev/null +++ b/arch/m68knommu/lib/semaphore.S | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/lib/semaphore.S | ||
3 | * | ||
4 | * Copyright (C) 1996 Linus Torvalds | ||
5 | * | ||
6 | * m68k version by Andreas Schwab | ||
7 | * | ||
8 | * MAR/1999 -- modified to support ColdFire (gerg@snapgear.com) | ||
9 | */ | ||
10 | |||
11 | #include <linux/linkage.h> | ||
12 | #include <linux/config.h> | ||
13 | #include <asm/semaphore.h> | ||
14 | |||
15 | /* | ||
16 | * "down_failed" is called with the eventual return address | ||
17 | * in %a0, and the address of the semaphore in %a1. We need | ||
18 | * to increment the number of waiters on the semaphore, | ||
19 | * call "__down()", and then eventually return to try again. | ||
20 | */ | ||
21 | ENTRY(__down_failed) | ||
22 | #ifdef CONFIG_COLDFIRE | ||
23 | subl #12,%sp | ||
24 | moveml %a0/%d0/%d1,(%sp) | ||
25 | #else | ||
26 | moveml %a0/%d0/%d1,-(%sp) | ||
27 | #endif | ||
28 | movel %a1,-(%sp) | ||
29 | jbsr __down | ||
30 | movel (%sp)+,%a1 | ||
31 | movel (%sp)+,%d0 | ||
32 | movel (%sp)+,%d1 | ||
33 | rts | ||
34 | |||
35 | ENTRY(__down_failed_interruptible) | ||
36 | movel %a0,-(%sp) | ||
37 | movel %d1,-(%sp) | ||
38 | movel %a1,-(%sp) | ||
39 | jbsr __down_interruptible | ||
40 | movel (%sp)+,%a1 | ||
41 | movel (%sp)+,%d1 | ||
42 | rts | ||
43 | |||
44 | ENTRY(__up_wakeup) | ||
45 | #ifdef CONFIG_COLDFIRE | ||
46 | subl #12,%sp | ||
47 | moveml %a0/%d0/%d1,(%sp) | ||
48 | #else | ||
49 | moveml %a0/%d0/%d1,-(%sp) | ||
50 | #endif | ||
51 | movel %a1,-(%sp) | ||
52 | jbsr __up | ||
53 | movel (%sp)+,%a1 | ||
54 | movel (%sp)+,%d0 | ||
55 | movel (%sp)+,%d1 | ||
56 | rts | ||
57 | |||
58 | ENTRY(__down_failed_trylock) | ||
59 | movel %a0,-(%sp) | ||
60 | movel %d1,-(%sp) | ||
61 | movel %a1,-(%sp) | ||
62 | jbsr __down_trylock | ||
63 | movel (%sp)+,%a1 | ||
64 | movel (%sp)+,%d1 | ||
65 | movel (%sp)+,%a0 | ||
66 | rts | ||
67 | |||
diff --git a/arch/m68knommu/lib/udivsi3.S b/arch/m68knommu/lib/udivsi3.S new file mode 100644 index 000000000000..c424c4a1f0a3 --- /dev/null +++ b/arch/m68knommu/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/m68knommu/lib/umodsi3.S b/arch/m68knommu/lib/umodsi3.S new file mode 100644 index 000000000000..5def5f626478 --- /dev/null +++ b/arch/m68knommu/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 | |||