diff options
Diffstat (limited to 'arch/frv/lib')
-rw-r--r-- | arch/frv/lib/Makefile | 8 | ||||
-rw-r--r-- | arch/frv/lib/__ashldi3.S | 40 | ||||
-rw-r--r-- | arch/frv/lib/__ashrdi3.S | 41 | ||||
-rw-r--r-- | arch/frv/lib/__lshrdi3.S | 40 | ||||
-rw-r--r-- | arch/frv/lib/__muldi3.S | 32 | ||||
-rw-r--r-- | arch/frv/lib/__negdi2.S | 28 | ||||
-rw-r--r-- | arch/frv/lib/atomic-ops.S | 265 | ||||
-rw-r--r-- | arch/frv/lib/cache.S | 98 | ||||
-rw-r--r-- | arch/frv/lib/checksum.c | 148 | ||||
-rw-r--r-- | arch/frv/lib/insl_ns.S | 52 | ||||
-rw-r--r-- | arch/frv/lib/insl_sw.S | 40 | ||||
-rw-r--r-- | arch/frv/lib/memcpy.S | 135 | ||||
-rw-r--r-- | arch/frv/lib/memset.S | 182 | ||||
-rw-r--r-- | arch/frv/lib/outsl_ns.S | 59 | ||||
-rw-r--r-- | arch/frv/lib/outsl_sw.S | 45 |
15 files changed, 1213 insertions, 0 deletions
diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile new file mode 100644 index 000000000000..19be2626d5e6 --- /dev/null +++ b/arch/frv/lib/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for FRV-specific library files.. | ||
3 | # | ||
4 | |||
5 | lib-y := \ | ||
6 | __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o \ | ||
7 | checksum.o memcpy.o memset.o atomic-ops.o \ | ||
8 | outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o | ||
diff --git a/arch/frv/lib/__ashldi3.S b/arch/frv/lib/__ashldi3.S new file mode 100644 index 000000000000..db5b6dc37a11 --- /dev/null +++ b/arch/frv/lib/__ashldi3.S | |||
@@ -0,0 +1,40 @@ | |||
1 | /* __ashldi3.S: 64-bit arithmetic shift left | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | .text | ||
13 | .p2align 4 | ||
14 | |||
15 | ############################################################################### | ||
16 | # | ||
17 | # unsigned long long __ashldi3(unsigned long long value [GR8:GR9], unsigned by [GR10]) | ||
18 | # | ||
19 | ############################################################################### | ||
20 | .globl __ashldi3 | ||
21 | .type __ashldi3,@function | ||
22 | __ashldi3: | ||
23 | andicc.p gr10,#63,gr10,icc0 | ||
24 | setlos #32,gr5 | ||
25 | andicc.p gr10,#32,gr0,icc1 | ||
26 | beqlr icc0,#0 | ||
27 | ckeq icc1,cc4 ; cc4 is true if 0<N<32 | ||
28 | |||
29 | # deal with a shift in the range 1<=N<=31 | ||
30 | csll.p gr8,gr10,gr8 ,cc4,#1 ; MSW <<= N | ||
31 | csub gr5,gr10,gr5 ,cc4,#1 ; M = 32 - N | ||
32 | csrl.p gr9,gr5,gr4 ,cc4,#1 | ||
33 | csll gr9,gr10,gr9 ,cc4,#1 ; LSW <<= N | ||
34 | cor.p gr4,gr8,gr8 ,cc4,#1 ; MSW |= LSW >> M | ||
35 | |||
36 | # deal with a shift in the range 32<=N<=63 | ||
37 | csll gr9,gr10,gr8 ,cc4,#0 ; MSW = LSW << (N & 31 [implicit AND]) | ||
38 | cor.p gr0,gr0,gr9 ,cc4,#0 ; LSW = 0 | ||
39 | bralr | ||
40 | .size __ashldi3, .-__ashldi3 | ||
diff --git a/arch/frv/lib/__ashrdi3.S b/arch/frv/lib/__ashrdi3.S new file mode 100644 index 000000000000..5742665bfd29 --- /dev/null +++ b/arch/frv/lib/__ashrdi3.S | |||
@@ -0,0 +1,41 @@ | |||
1 | /* __ashrdi3.S: 64-bit arithmetic shift right | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | .text | ||
13 | .p2align 4 | ||
14 | |||
15 | ############################################################################### | ||
16 | # | ||
17 | # signed long long __ashrdi3(signed long long value [GR8:GR9], unsigned by [GR10]) | ||
18 | # | ||
19 | ############################################################################### | ||
20 | .globl __ashrdi3 | ||
21 | .type __ashrdi3,@function | ||
22 | __ashrdi3: | ||
23 | andicc.p gr10,#63,gr10,icc0 | ||
24 | setlos #32,gr5 | ||
25 | andicc.p gr10,#32,gr0,icc1 | ||
26 | beqlr icc0,#0 | ||
27 | setlos.p #31,gr6 | ||
28 | ckeq icc1,cc4 ; cc4 is true if 0<N<32 | ||
29 | |||
30 | # deal with a shift in the range 1<=N<=31 | ||
31 | csrl.p gr9,gr10,gr9 ,cc4,#1 ; LSW >>= N | ||
32 | csub gr5,gr10,gr5 ,cc4,#1 ; M = 32 - N | ||
33 | csll.p gr8,gr5,gr4 ,cc4,#1 | ||
34 | csra gr8,gr10,gr8 ,cc4,#1 ; MSW >>= N | ||
35 | cor.p gr4,gr9,gr9 ,cc4,#1 ; LSW |= MSW << M | ||
36 | |||
37 | # deal with a shift in the range 32<=N<=63 | ||
38 | csra gr8,gr10,gr9 ,cc4,#0 ; LSW = MSW >> (N & 31 [implicit AND]) | ||
39 | csra.p gr8,gr6,gr8 ,cc4,#0 ; MSW >>= 31 | ||
40 | bralr | ||
41 | .size __ashrdi3, .-__ashrdi3 | ||
diff --git a/arch/frv/lib/__lshrdi3.S b/arch/frv/lib/__lshrdi3.S new file mode 100644 index 000000000000..7b41f6304f04 --- /dev/null +++ b/arch/frv/lib/__lshrdi3.S | |||
@@ -0,0 +1,40 @@ | |||
1 | /* __lshrdi3.S: 64-bit logical shift right | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | .text | ||
13 | .p2align 4 | ||
14 | |||
15 | ############################################################################### | ||
16 | # | ||
17 | # unsigned long long __lshrdi3(unsigned long long value [GR8:GR9], unsigned by [GR10]) | ||
18 | # | ||
19 | ############################################################################### | ||
20 | .globl __lshrdi3 | ||
21 | .type __lshrdi3,@function | ||
22 | __lshrdi3: | ||
23 | andicc.p gr10,#63,gr10,icc0 | ||
24 | setlos #32,gr5 | ||
25 | andicc.p gr10,#32,gr0,icc1 | ||
26 | beqlr icc0,#0 | ||
27 | ckeq icc1,cc4 ; cc4 is true if 0<N<32 | ||
28 | |||
29 | # deal with a shift in the range 1<=N<=31 | ||
30 | csrl.p gr9,gr10,gr9 ,cc4,#1 ; LSW >>= N | ||
31 | csub gr5,gr10,gr5 ,cc4,#1 ; M = 32 - N | ||
32 | csll.p gr8,gr5,gr4 ,cc4,#1 | ||
33 | csrl gr8,gr10,gr8 ,cc4,#1 ; MSW >>= N | ||
34 | cor.p gr4,gr9,gr9 ,cc4,#1 ; LSW |= MSW << M | ||
35 | |||
36 | # deal with a shift in the range 32<=N<=63 | ||
37 | csrl gr8,gr10,gr9 ,cc4,#0 ; LSW = MSW >> (N & 31 [implicit AND]) | ||
38 | cor.p gr0,gr0,gr8 ,cc4,#0 ; MSW = 0 | ||
39 | bralr | ||
40 | .size __lshrdi3, .-__lshrdi3 | ||
diff --git a/arch/frv/lib/__muldi3.S b/arch/frv/lib/__muldi3.S new file mode 100644 index 000000000000..2703d9b79361 --- /dev/null +++ b/arch/frv/lib/__muldi3.S | |||
@@ -0,0 +1,32 @@ | |||
1 | /* __muldi3.S: 64-bit multiply | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | .text | ||
13 | .p2align 4 | ||
14 | |||
15 | ############################################################################### | ||
16 | # | ||
17 | # unsigned long long __muldi3(unsigned long long x [GR8:GR9], | ||
18 | # unsigned long long y [GR10:GR11]) | ||
19 | # | ||
20 | ############################################################################### | ||
21 | .globl __muldi3, __mulll, __umulll | ||
22 | .type __muldi3,@function | ||
23 | __muldi3: | ||
24 | __mulll: | ||
25 | __umulll: | ||
26 | umul gr8,gr11,gr4 ; GR4:GR5 = x.MSW * y.LSW | ||
27 | umul gr9,gr10,gr6 ; GR6:GR7 = x.LSW * y.MSW | ||
28 | umul.p gr9,gr11,gr8 ; GR8:GR9 = x.LSW * y.LSW | ||
29 | add gr5,gr7,gr5 | ||
30 | add.p gr8,gr5,gr8 ; GR8 += GR5 + GR7 | ||
31 | bralr | ||
32 | .size __muldi3, .-__muldi3 | ||
diff --git a/arch/frv/lib/__negdi2.S b/arch/frv/lib/__negdi2.S new file mode 100644 index 000000000000..d1747bf24997 --- /dev/null +++ b/arch/frv/lib/__negdi2.S | |||
@@ -0,0 +1,28 @@ | |||
1 | /* __negdi2.S: 64-bit negate | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | .text | ||
14 | .p2align 4 | ||
15 | |||
16 | ############################################################################### | ||
17 | # | ||
18 | # unsigned long long __negdi2(unsigned long long value [GR8:GR9]) | ||
19 | # | ||
20 | ############################################################################### | ||
21 | .globl __negdi2 | ||
22 | .type __negdi2,@function | ||
23 | __negdi2: | ||
24 | subcc gr0,gr9,gr9,icc0 | ||
25 | subx gr0,gr8,gr8,icc0 | ||
26 | bralr | ||
27 | .size __negdi2, .-__negdi2 | ||
28 | |||
diff --git a/arch/frv/lib/atomic-ops.S b/arch/frv/lib/atomic-ops.S new file mode 100644 index 000000000000..b03d510a89e4 --- /dev/null +++ b/arch/frv/lib/atomic-ops.S | |||
@@ -0,0 +1,265 @@ | |||
1 | /* atomic-ops.S: kernel atomic operations | ||
2 | * | ||
3 | * For an explanation of how atomic ops work in this arch, see: | ||
4 | * Documentation/fujitsu/frv/atomic-ops.txt | ||
5 | * | ||
6 | * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. | ||
7 | * Written by David Howells (dhowells@redhat.com) | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #include <asm/spr-regs.h> | ||
16 | |||
17 | .text | ||
18 | .balign 4 | ||
19 | |||
20 | ############################################################################### | ||
21 | # | ||
22 | # unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v); | ||
23 | # | ||
24 | ############################################################################### | ||
25 | .globl atomic_test_and_ANDNOT_mask | ||
26 | .type atomic_test_and_ANDNOT_mask,@function | ||
27 | atomic_test_and_ANDNOT_mask: | ||
28 | not.p gr8,gr10 | ||
29 | 0: | ||
30 | orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ | ||
31 | ckeq icc3,cc7 | ||
32 | ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */ | ||
33 | orcr cc7,cc7,cc3 /* set CC3 to true */ | ||
34 | and gr8,gr10,gr11 | ||
35 | cst.p gr11,@(gr9,gr0) ,cc3,#1 | ||
36 | corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ | ||
37 | beq icc3,#0,0b | ||
38 | bralr | ||
39 | |||
40 | .size atomic_test_and_ANDNOT_mask, .-atomic_test_and_ANDNOT_mask | ||
41 | |||
42 | ############################################################################### | ||
43 | # | ||
44 | # unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v); | ||
45 | # | ||
46 | ############################################################################### | ||
47 | .globl atomic_test_and_OR_mask | ||
48 | .type atomic_test_and_OR_mask,@function | ||
49 | atomic_test_and_OR_mask: | ||
50 | or.p gr8,gr8,gr10 | ||
51 | 0: | ||
52 | orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ | ||
53 | ckeq icc3,cc7 | ||
54 | ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */ | ||
55 | orcr cc7,cc7,cc3 /* set CC3 to true */ | ||
56 | or gr8,gr10,gr11 | ||
57 | cst.p gr11,@(gr9,gr0) ,cc3,#1 | ||
58 | corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ | ||
59 | beq icc3,#0,0b | ||
60 | bralr | ||
61 | |||
62 | .size atomic_test_and_OR_mask, .-atomic_test_and_OR_mask | ||
63 | |||
64 | ############################################################################### | ||
65 | # | ||
66 | # unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v); | ||
67 | # | ||
68 | ############################################################################### | ||
69 | .globl atomic_test_and_XOR_mask | ||
70 | .type atomic_test_and_XOR_mask,@function | ||
71 | atomic_test_and_XOR_mask: | ||
72 | or.p gr8,gr8,gr10 | ||
73 | 0: | ||
74 | orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ | ||
75 | ckeq icc3,cc7 | ||
76 | ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */ | ||
77 | orcr cc7,cc7,cc3 /* set CC3 to true */ | ||
78 | xor gr8,gr10,gr11 | ||
79 | cst.p gr11,@(gr9,gr0) ,cc3,#1 | ||
80 | corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ | ||
81 | beq icc3,#0,0b | ||
82 | bralr | ||
83 | |||
84 | .size atomic_test_and_XOR_mask, .-atomic_test_and_XOR_mask | ||
85 | |||
86 | ############################################################################### | ||
87 | # | ||
88 | # int atomic_add_return(int i, atomic_t *v) | ||
89 | # | ||
90 | ############################################################################### | ||
91 | .globl atomic_add_return | ||
92 | .type atomic_add_return,@function | ||
93 | atomic_add_return: | ||
94 | or.p gr8,gr8,gr10 | ||
95 | 0: | ||
96 | orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ | ||
97 | ckeq icc3,cc7 | ||
98 | ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */ | ||
99 | orcr cc7,cc7,cc3 /* set CC3 to true */ | ||
100 | add gr8,gr10,gr8 | ||
101 | cst.p gr8,@(gr9,gr0) ,cc3,#1 | ||
102 | corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ | ||
103 | beq icc3,#0,0b | ||
104 | bralr | ||
105 | |||
106 | .size atomic_add_return, .-atomic_add_return | ||
107 | |||
108 | ############################################################################### | ||
109 | # | ||
110 | # int atomic_sub_return(int i, atomic_t *v) | ||
111 | # | ||
112 | ############################################################################### | ||
113 | .globl atomic_sub_return | ||
114 | .type atomic_sub_return,@function | ||
115 | atomic_sub_return: | ||
116 | or.p gr8,gr8,gr10 | ||
117 | 0: | ||
118 | orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ | ||
119 | ckeq icc3,cc7 | ||
120 | ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */ | ||
121 | orcr cc7,cc7,cc3 /* set CC3 to true */ | ||
122 | sub gr8,gr10,gr8 | ||
123 | cst.p gr8,@(gr9,gr0) ,cc3,#1 | ||
124 | corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ | ||
125 | beq icc3,#0,0b | ||
126 | bralr | ||
127 | |||
128 | .size atomic_sub_return, .-atomic_sub_return | ||
129 | |||
130 | ############################################################################### | ||
131 | # | ||
132 | # uint8_t __xchg_8(uint8_t i, uint8_t *v) | ||
133 | # | ||
134 | ############################################################################### | ||
135 | .globl __xchg_8 | ||
136 | .type __xchg_8,@function | ||
137 | __xchg_8: | ||
138 | or.p gr8,gr8,gr10 | ||
139 | 0: | ||
140 | orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ | ||
141 | ckeq icc3,cc7 | ||
142 | ldub.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */ | ||
143 | orcr cc7,cc7,cc3 /* set CC3 to true */ | ||
144 | cstb.p gr10,@(gr9,gr0) ,cc3,#1 | ||
145 | corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ | ||
146 | beq icc3,#0,0b | ||
147 | bralr | ||
148 | |||
149 | .size __xchg_8, .-__xchg_8 | ||
150 | |||
151 | ############################################################################### | ||
152 | # | ||
153 | # uint16_t __xchg_16(uint16_t i, uint16_t *v) | ||
154 | # | ||
155 | ############################################################################### | ||
156 | .globl __xchg_16 | ||
157 | .type __xchg_16,@function | ||
158 | __xchg_16: | ||
159 | or.p gr8,gr8,gr10 | ||
160 | 0: | ||
161 | orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ | ||
162 | ckeq icc3,cc7 | ||
163 | lduh.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */ | ||
164 | orcr cc7,cc7,cc3 /* set CC3 to true */ | ||
165 | csth.p gr10,@(gr9,gr0) ,cc3,#1 | ||
166 | corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ | ||
167 | beq icc3,#0,0b | ||
168 | bralr | ||
169 | |||
170 | .size __xchg_16, .-__xchg_16 | ||
171 | |||
172 | ############################################################################### | ||
173 | # | ||
174 | # uint32_t __xchg_32(uint32_t i, uint32_t *v) | ||
175 | # | ||
176 | ############################################################################### | ||
177 | .globl __xchg_32 | ||
178 | .type __xchg_32,@function | ||
179 | __xchg_32: | ||
180 | or.p gr8,gr8,gr10 | ||
181 | 0: | ||
182 | orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ | ||
183 | ckeq icc3,cc7 | ||
184 | ld.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */ | ||
185 | orcr cc7,cc7,cc3 /* set CC3 to true */ | ||
186 | cst.p gr10,@(gr9,gr0) ,cc3,#1 | ||
187 | corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ | ||
188 | beq icc3,#0,0b | ||
189 | bralr | ||
190 | |||
191 | .size __xchg_32, .-__xchg_32 | ||
192 | |||
193 | ############################################################################### | ||
194 | # | ||
195 | # uint8_t __cmpxchg_8(uint8_t *v, uint8_t test, uint8_t new) | ||
196 | # | ||
197 | ############################################################################### | ||
198 | .globl __cmpxchg_8 | ||
199 | .type __cmpxchg_8,@function | ||
200 | __cmpxchg_8: | ||
201 | or.p gr8,gr8,gr11 | ||
202 | 0: | ||
203 | orcc gr0,gr0,gr0,icc3 | ||
204 | ckeq icc3,cc7 | ||
205 | ldub.p @(gr11,gr0),gr8 | ||
206 | orcr cc7,cc7,cc3 | ||
207 | sub gr8,gr9,gr7 | ||
208 | sllicc gr7,#24,gr0,icc0 | ||
209 | bne icc0,#0,1f | ||
210 | cstb.p gr10,@(gr11,gr0) ,cc3,#1 | ||
211 | corcc gr29,gr29,gr0 ,cc3,#1 | ||
212 | beq icc3,#0,0b | ||
213 | 1: | ||
214 | bralr | ||
215 | |||
216 | .size __cmpxchg_8, .-__cmpxchg_8 | ||
217 | |||
218 | ############################################################################### | ||
219 | # | ||
220 | # uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new) | ||
221 | # | ||
222 | ############################################################################### | ||
223 | .globl __cmpxchg_16 | ||
224 | .type __cmpxchg_16,@function | ||
225 | __cmpxchg_16: | ||
226 | or.p gr8,gr8,gr11 | ||
227 | 0: | ||
228 | orcc gr0,gr0,gr0,icc3 | ||
229 | ckeq icc3,cc7 | ||
230 | lduh.p @(gr11,gr0),gr8 | ||
231 | orcr cc7,cc7,cc3 | ||
232 | sub gr8,gr9,gr7 | ||
233 | sllicc gr7,#16,gr0,icc0 | ||
234 | bne icc0,#0,1f | ||
235 | csth.p gr10,@(gr11,gr0) ,cc3,#1 | ||
236 | corcc gr29,gr29,gr0 ,cc3,#1 | ||
237 | beq icc3,#0,0b | ||
238 | 1: | ||
239 | bralr | ||
240 | |||
241 | .size __cmpxchg_16, .-__cmpxchg_16 | ||
242 | |||
243 | ############################################################################### | ||
244 | # | ||
245 | # uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new) | ||
246 | # | ||
247 | ############################################################################### | ||
248 | .globl __cmpxchg_32 | ||
249 | .type __cmpxchg_32,@function | ||
250 | __cmpxchg_32: | ||
251 | or.p gr8,gr8,gr11 | ||
252 | 0: | ||
253 | orcc gr0,gr0,gr0,icc3 | ||
254 | ckeq icc3,cc7 | ||
255 | ld.p @(gr11,gr0),gr8 | ||
256 | orcr cc7,cc7,cc3 | ||
257 | subcc gr8,gr9,gr7,icc0 | ||
258 | bne icc0,#0,1f | ||
259 | cst.p gr10,@(gr11,gr0) ,cc3,#1 | ||
260 | corcc gr29,gr29,gr0 ,cc3,#1 | ||
261 | beq icc3,#0,0b | ||
262 | 1: | ||
263 | bralr | ||
264 | |||
265 | .size __cmpxchg_32, .-__cmpxchg_32 | ||
diff --git a/arch/frv/lib/cache.S b/arch/frv/lib/cache.S new file mode 100644 index 000000000000..0e10ad8dc462 --- /dev/null +++ b/arch/frv/lib/cache.S | |||
@@ -0,0 +1,98 @@ | |||
1 | /* cache.S: cache managment routines | ||
2 | * | ||
3 | * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <asm/spr-regs.h> | ||
13 | #include <asm/cache.h> | ||
14 | |||
15 | .text | ||
16 | .p2align 4 | ||
17 | |||
18 | ############################################################################### | ||
19 | # | ||
20 | # Write back a range of dcache | ||
21 | # - void frv_dcache_writeback(unsigned long start [GR8], unsigned long size [GR9]) | ||
22 | # | ||
23 | ############################################################################### | ||
24 | .globl frv_dcache_writeback | ||
25 | .type frv_dcache_writeback,@function | ||
26 | frv_dcache_writeback: | ||
27 | andi gr8,~(L1_CACHE_BYTES-1),gr8 | ||
28 | |||
29 | 2: dcf @(gr8,gr0) | ||
30 | addi gr8,#L1_CACHE_BYTES,gr8 | ||
31 | cmp gr9,gr8,icc0 | ||
32 | bhi icc0,#2,2b | ||
33 | |||
34 | membar | ||
35 | bralr | ||
36 | .size frv_dcache_writeback, .-frv_dcache_writeback | ||
37 | |||
38 | ############################################################################## | ||
39 | # | ||
40 | # Invalidate a range of dcache and icache | ||
41 | # - void frv_cache_invalidate(unsigned long start [GR8], unsigned long end [GR9]); | ||
42 | # | ||
43 | ############################################################################### | ||
44 | .globl frv_cache_invalidate | ||
45 | .type frv_cache_invalidate,@function | ||
46 | frv_cache_invalidate: | ||
47 | andi gr8,~(L1_CACHE_BYTES-1),gr8 | ||
48 | |||
49 | 2: dci @(gr8,gr0) | ||
50 | ici @(gr8,gr0) | ||
51 | addi gr8,#L1_CACHE_BYTES,gr8 | ||
52 | cmp gr9,gr8,icc0 | ||
53 | bhi icc0,#2,2b | ||
54 | |||
55 | membar | ||
56 | bralr | ||
57 | .size frv_cache_invalidate, .-frv_cache_invalidate | ||
58 | |||
59 | ############################################################################## | ||
60 | # | ||
61 | # Invalidate a range of icache | ||
62 | # - void frv_icache_invalidate(unsigned long start [GR8], unsigned long end [GR9]); | ||
63 | # | ||
64 | ############################################################################### | ||
65 | .globl frv_icache_invalidate | ||
66 | .type frv_icache_invalidate,@function | ||
67 | frv_icache_invalidate: | ||
68 | andi gr8,~(L1_CACHE_BYTES-1),gr8 | ||
69 | |||
70 | 2: ici @(gr8,gr0) | ||
71 | addi gr8,#L1_CACHE_BYTES,gr8 | ||
72 | cmp gr9,gr8,icc0 | ||
73 | bhi icc0,#2,2b | ||
74 | |||
75 | membar | ||
76 | bralr | ||
77 | .size frv_icache_invalidate, .-frv_icache_invalidate | ||
78 | |||
79 | ############################################################################### | ||
80 | # | ||
81 | # Write back and invalidate a range of dcache and icache | ||
82 | # - void frv_cache_wback_inv(unsigned long start [GR8], unsigned long end [GR9]) | ||
83 | # | ||
84 | ############################################################################### | ||
85 | .globl frv_cache_wback_inv | ||
86 | .type frv_cache_wback_inv,@function | ||
87 | frv_cache_wback_inv: | ||
88 | andi gr8,~(L1_CACHE_BYTES-1),gr8 | ||
89 | |||
90 | 2: dcf @(gr8,gr0) | ||
91 | ici @(gr8,gr0) | ||
92 | addi gr8,#L1_CACHE_BYTES,gr8 | ||
93 | cmp gr9,gr8,icc0 | ||
94 | bhi icc0,#2,2b | ||
95 | |||
96 | membar | ||
97 | bralr | ||
98 | .size frv_cache_wback_inv, .-frv_cache_wback_inv | ||
diff --git a/arch/frv/lib/checksum.c b/arch/frv/lib/checksum.c new file mode 100644 index 000000000000..7bf5bd6cac8a --- /dev/null +++ b/arch/frv/lib/checksum.c | |||
@@ -0,0 +1,148 @@ | |||
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 <net/checksum.h> | ||
35 | #include <asm/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 | * computes the checksum of a memory block at buff, length len, | ||
97 | * and adds in "sum" (32-bit) | ||
98 | * | ||
99 | * returns a 32-bit number suitable for feeding into itself | ||
100 | * or csum_tcpudp_magic | ||
101 | * | ||
102 | * this function must be called with even lengths, except | ||
103 | * for the last fragment, which may be odd | ||
104 | * | ||
105 | * it's best to have buff aligned on a 32-bit boundary | ||
106 | */ | ||
107 | unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) | ||
108 | { | ||
109 | unsigned int result = do_csum(buff, len); | ||
110 | |||
111 | /* add in old sum, and carry.. */ | ||
112 | result += sum; | ||
113 | if (sum > result) | ||
114 | result += 1; | ||
115 | return result; | ||
116 | } | ||
117 | |||
118 | /* | ||
119 | * this routine is used for miscellaneous IP-like checksums, mainly | ||
120 | * in icmp.c | ||
121 | */ | ||
122 | unsigned short ip_compute_csum(const unsigned char * buff, int len) | ||
123 | { | ||
124 | return ~do_csum(buff,len); | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * copy from fs while checksumming, otherwise like csum_partial | ||
129 | */ | ||
130 | |||
131 | unsigned int | ||
132 | csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err) | ||
133 | { | ||
134 | if (csum_err) *csum_err = 0; | ||
135 | memcpy(dst, src, len); | ||
136 | return csum_partial(dst, len, sum); | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * copy from ds while checksumming, otherwise like csum_partial | ||
141 | */ | ||
142 | |||
143 | unsigned int | ||
144 | csum_partial_copy(const char *src, char *dst, int len, int sum) | ||
145 | { | ||
146 | memcpy(dst, src, len); | ||
147 | return csum_partial(dst, len, sum); | ||
148 | } | ||
diff --git a/arch/frv/lib/insl_ns.S b/arch/frv/lib/insl_ns.S new file mode 100644 index 000000000000..d1658425a9f7 --- /dev/null +++ b/arch/frv/lib/insl_ns.S | |||
@@ -0,0 +1,52 @@ | |||
1 | /* insl_ns.S: input array of 4b words from device port without byte swapping | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | .text | ||
14 | .p2align 4 | ||
15 | |||
16 | ############################################################################### | ||
17 | # | ||
18 | # void __insl_ns(unsigned int port, void *buf, int n) | ||
19 | # | ||
20 | ############################################################################### | ||
21 | .globl __insl_ns | ||
22 | .type __insl_ns,@function | ||
23 | __insl_ns: | ||
24 | andicc.p gr9,#3,gr0,icc0 | ||
25 | setlos #4,gr4 | ||
26 | bne icc0,#0,__insl_ns_misaligned | ||
27 | subi gr9,#4,gr9 | ||
28 | 0: | ||
29 | ldi.p @(gr8,#0),gr5 | ||
30 | subicc gr10,#1,gr10,icc0 | ||
31 | stu.p gr5,@(gr9,gr4) | ||
32 | bhi icc0,#2,0b | ||
33 | bralr | ||
34 | |||
35 | __insl_ns_misaligned: | ||
36 | subi.p gr9,#1,gr9 | ||
37 | setlos #1,gr4 | ||
38 | 0: | ||
39 | ldi @(gr8,#0),gr5 | ||
40 | |||
41 | srli gr5,#24,gr6 | ||
42 | stbu.p gr6,@(gr9,gr4) | ||
43 | srli gr5,#16,gr6 | ||
44 | stbu.p gr6,@(gr9,gr4) | ||
45 | srli gr5,#8,gr6 | ||
46 | stbu.p gr6,@(gr9,gr4) | ||
47 | subicc gr10,#1,gr10,icc0 | ||
48 | stbu.p gr5,@(gr9,gr4) | ||
49 | bhi icc0,#2,0b | ||
50 | bralr | ||
51 | |||
52 | .size __insl_ns, .-__insl_ns | ||
diff --git a/arch/frv/lib/insl_sw.S b/arch/frv/lib/insl_sw.S new file mode 100644 index 000000000000..9b5aa95d069b --- /dev/null +++ b/arch/frv/lib/insl_sw.S | |||
@@ -0,0 +1,40 @@ | |||
1 | /* insl_sw.S: input array of 4b words from device port with byte swapping | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | .text | ||
14 | .p2align 4 | ||
15 | |||
16 | ############################################################################### | ||
17 | # | ||
18 | # void __insl_sw(unsigned int port, void *buf, int n) | ||
19 | # | ||
20 | ############################################################################### | ||
21 | .globl __insl_sw | ||
22 | .type __insl_sw,@function | ||
23 | __insl_sw: | ||
24 | subi.p gr9,#1,gr9 | ||
25 | setlos #1,gr4 | ||
26 | 0: | ||
27 | ldi.p @(gr8,#0),gr5 ; get 0xAABBCCDD | ||
28 | subicc gr10,#1,gr10,icc0 | ||
29 | |||
30 | stbu.p gr5,@(gr9,gr4) ; write 0xDD | ||
31 | srli gr5,#8,gr5 | ||
32 | stbu.p gr5,@(gr9,gr4) ; write 0xCC | ||
33 | srli gr5,#8,gr5 | ||
34 | stbu.p gr5,@(gr9,gr4) ; write 0xBB | ||
35 | srli gr5,#8,gr5 | ||
36 | stbu.p gr5,@(gr9,gr4) ; write 0xAA | ||
37 | bhi icc0,#2,0b | ||
38 | bralr | ||
39 | |||
40 | .size __insl_sw, .-__insl_sw | ||
diff --git a/arch/frv/lib/memcpy.S b/arch/frv/lib/memcpy.S new file mode 100644 index 000000000000..9c5965273428 --- /dev/null +++ b/arch/frv/lib/memcpy.S | |||
@@ -0,0 +1,135 @@ | |||
1 | /* memcpy.S: optimised assembly memcpy | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | .text | ||
14 | .p2align 4 | ||
15 | |||
16 | ############################################################################### | ||
17 | # | ||
18 | # void *memcpy(void *to, const char *from, size_t count) | ||
19 | # | ||
20 | # - NOTE: must not use any stack. exception detection performs function return | ||
21 | # to caller's fixup routine, aborting the remainder of the copy | ||
22 | # | ||
23 | ############################################################################### | ||
24 | .globl memcpy,__memcpy_end | ||
25 | .type memcpy,@function | ||
26 | memcpy: | ||
27 | or.p gr8,gr9,gr4 | ||
28 | orcc gr10,gr0,gr0,icc3 | ||
29 | or.p gr10,gr4,gr4 | ||
30 | beqlr icc3,#0 | ||
31 | |||
32 | # optimise based on best common alignment for to, from & count | ||
33 | andicc.p gr4,#0x0f,gr0,icc0 | ||
34 | setlos #8,gr11 | ||
35 | andicc.p gr4,#0x07,gr0,icc1 | ||
36 | beq icc0,#0,memcpy_16 | ||
37 | andicc.p gr4,#0x03,gr0,icc0 | ||
38 | beq icc1,#0,memcpy_8 | ||
39 | andicc.p gr4,#0x01,gr0,icc1 | ||
40 | beq icc0,#0,memcpy_4 | ||
41 | setlos.p #1,gr11 | ||
42 | beq icc1,#0,memcpy_2 | ||
43 | |||
44 | # do byte by byte copy | ||
45 | sub.p gr8,gr11,gr3 | ||
46 | sub gr9,gr11,gr9 | ||
47 | 0: ldubu.p @(gr9,gr11),gr4 | ||
48 | subicc gr10,#1,gr10,icc0 | ||
49 | stbu.p gr4,@(gr3,gr11) | ||
50 | bne icc0,#2,0b | ||
51 | bralr | ||
52 | |||
53 | # do halfword by halfword copy | ||
54 | memcpy_2: | ||
55 | setlos #2,gr11 | ||
56 | sub.p gr8,gr11,gr3 | ||
57 | sub gr9,gr11,gr9 | ||
58 | 0: lduhu.p @(gr9,gr11),gr4 | ||
59 | subicc gr10,#2,gr10,icc0 | ||
60 | sthu.p gr4,@(gr3,gr11) | ||
61 | bne icc0,#2,0b | ||
62 | bralr | ||
63 | |||
64 | # do word by word copy | ||
65 | memcpy_4: | ||
66 | setlos #4,gr11 | ||
67 | sub.p gr8,gr11,gr3 | ||
68 | sub gr9,gr11,gr9 | ||
69 | 0: ldu.p @(gr9,gr11),gr4 | ||
70 | subicc gr10,#4,gr10,icc0 | ||
71 | stu.p gr4,@(gr3,gr11) | ||
72 | bne icc0,#2,0b | ||
73 | bralr | ||
74 | |||
75 | # do double-word by double-word copy | ||
76 | memcpy_8: | ||
77 | sub.p gr8,gr11,gr3 | ||
78 | sub gr9,gr11,gr9 | ||
79 | 0: lddu.p @(gr9,gr11),gr4 | ||
80 | subicc gr10,#8,gr10,icc0 | ||
81 | stdu.p gr4,@(gr3,gr11) | ||
82 | bne icc0,#2,0b | ||
83 | bralr | ||
84 | |||
85 | # do quad-word by quad-word copy | ||
86 | memcpy_16: | ||
87 | sub.p gr8,gr11,gr3 | ||
88 | sub gr9,gr11,gr9 | ||
89 | 0: lddu @(gr9,gr11),gr4 | ||
90 | lddu.p @(gr9,gr11),gr6 | ||
91 | subicc gr10,#16,gr10,icc0 | ||
92 | stdu gr4,@(gr3,gr11) | ||
93 | stdu.p gr6,@(gr3,gr11) | ||
94 | bne icc0,#2,0b | ||
95 | bralr | ||
96 | __memcpy_end: | ||
97 | |||
98 | .size memcpy, __memcpy_end-memcpy | ||
99 | |||
100 | ############################################################################### | ||
101 | # | ||
102 | # copy to/from userspace | ||
103 | # - return the number of bytes that could not be copied (0 on complete success) | ||
104 | # | ||
105 | # long __memcpy_user(void *dst, const void *src, size_t count) | ||
106 | # | ||
107 | ############################################################################### | ||
108 | .globl __memcpy_user, __memcpy_user_error_lr, __memcpy_user_error_handler | ||
109 | .type __memcpy_user,@function | ||
110 | __memcpy_user: | ||
111 | movsg lr,gr7 | ||
112 | subi.p sp,#8,sp | ||
113 | add gr8,gr10,gr6 ; calculate expected end address | ||
114 | stdi gr6,@(sp,#0) | ||
115 | |||
116 | # abuse memcpy to do the dirty work | ||
117 | call memcpy | ||
118 | __memcpy_user_error_lr: | ||
119 | ldi.p @(sp,#4),gr7 | ||
120 | setlos #0,gr8 | ||
121 | jmpl.p @(gr7,gr0) | ||
122 | addi sp,#8,sp | ||
123 | |||
124 | # deal any exception generated by memcpy | ||
125 | # GR8 - memcpy's current dest address | ||
126 | # GR11 - memset's step value (index register for store insns) | ||
127 | __memcpy_user_error_handler: | ||
128 | lddi.p @(sp,#0),gr4 ; load GR4 with dst+count, GR5 with ret addr | ||
129 | add gr11,gr3,gr7 | ||
130 | sub.p gr4,gr7,gr8 | ||
131 | |||
132 | addi sp,#8,sp | ||
133 | jmpl @(gr5,gr0) | ||
134 | |||
135 | .size __memcpy_user, .-__memcpy_user | ||
diff --git a/arch/frv/lib/memset.S b/arch/frv/lib/memset.S new file mode 100644 index 000000000000..55a35263cbe3 --- /dev/null +++ b/arch/frv/lib/memset.S | |||
@@ -0,0 +1,182 @@ | |||
1 | /* memset.S: optimised assembly memset | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | .text | ||
14 | .p2align 4 | ||
15 | |||
16 | ############################################################################### | ||
17 | # | ||
18 | # void *memset(void *p, char ch, size_t count) | ||
19 | # | ||
20 | # - NOTE: must not use any stack. exception detection performs function return | ||
21 | # to caller's fixup routine, aborting the remainder of the set | ||
22 | # GR4, GR7, GR8, and GR11 must be managed | ||
23 | # | ||
24 | ############################################################################### | ||
25 | .globl memset,__memset_end | ||
26 | .type memset,@function | ||
27 | memset: | ||
28 | orcc.p gr10,gr0,gr5,icc3 ; GR5 = count | ||
29 | andi gr9,#0xff,gr9 | ||
30 | or.p gr8,gr0,gr4 ; GR4 = address | ||
31 | beqlr icc3,#0 | ||
32 | |||
33 | # conditionally write a byte to 2b-align the address | ||
34 | setlos.p #1,gr6 | ||
35 | andicc gr4,#1,gr0,icc0 | ||
36 | ckne icc0,cc7 | ||
37 | cstb.p gr9,@(gr4,gr0) ,cc7,#1 | ||
38 | csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3 | ||
39 | cadd.p gr4,gr6,gr4 ,cc7,#1 | ||
40 | beqlr icc3,#0 | ||
41 | |||
42 | # conditionally write a word to 4b-align the address | ||
43 | andicc.p gr4,#2,gr0,icc0 | ||
44 | subicc gr5,#2,gr0,icc1 | ||
45 | setlos.p #2,gr6 | ||
46 | ckne icc0,cc7 | ||
47 | slli.p gr9,#8,gr12 ; need to double up the pattern | ||
48 | cknc icc1,cc5 | ||
49 | or.p gr9,gr12,gr12 | ||
50 | andcr cc7,cc5,cc7 | ||
51 | |||
52 | csth.p gr12,@(gr4,gr0) ,cc7,#1 | ||
53 | csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3 | ||
54 | cadd.p gr4,gr6,gr4 ,cc7,#1 | ||
55 | beqlr icc3,#0 | ||
56 | |||
57 | # conditionally write a dword to 8b-align the address | ||
58 | andicc.p gr4,#4,gr0,icc0 | ||
59 | subicc gr5,#4,gr0,icc1 | ||
60 | setlos.p #4,gr6 | ||
61 | ckne icc0,cc7 | ||
62 | slli.p gr12,#16,gr13 ; need to quadruple-up the pattern | ||
63 | cknc icc1,cc5 | ||
64 | or.p gr13,gr12,gr12 | ||
65 | andcr cc7,cc5,cc7 | ||
66 | |||
67 | cst.p gr12,@(gr4,gr0) ,cc7,#1 | ||
68 | csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3 | ||
69 | cadd.p gr4,gr6,gr4 ,cc7,#1 | ||
70 | beqlr icc3,#0 | ||
71 | |||
72 | or.p gr12,gr12,gr13 ; need to octuple-up the pattern | ||
73 | |||
74 | # the address is now 8b-aligned - loop around writing 64b chunks | ||
75 | setlos #8,gr7 | ||
76 | subi.p gr4,#8,gr4 ; store with update index does weird stuff | ||
77 | setlos #64,gr6 | ||
78 | |||
79 | subicc gr5,#64,gr0,icc0 | ||
80 | 0: cknc icc0,cc7 | ||
81 | cstdu gr12,@(gr4,gr7) ,cc7,#1 | ||
82 | cstdu gr12,@(gr4,gr7) ,cc7,#1 | ||
83 | cstdu gr12,@(gr4,gr7) ,cc7,#1 | ||
84 | cstdu gr12,@(gr4,gr7) ,cc7,#1 | ||
85 | cstdu gr12,@(gr4,gr7) ,cc7,#1 | ||
86 | cstdu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
87 | csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3 | ||
88 | cstdu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
89 | subicc gr5,#64,gr0,icc0 | ||
90 | cstdu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
91 | beqlr icc3,#0 | ||
92 | bnc icc0,#2,0b | ||
93 | |||
94 | # now do 32-byte remnant | ||
95 | subicc.p gr5,#32,gr0,icc0 | ||
96 | setlos #32,gr6 | ||
97 | cknc icc0,cc7 | ||
98 | cstdu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
99 | csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3 | ||
100 | cstdu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
101 | setlos #16,gr6 | ||
102 | cstdu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
103 | subicc gr5,#16,gr0,icc0 | ||
104 | cstdu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
105 | beqlr icc3,#0 | ||
106 | |||
107 | # now do 16-byte remnant | ||
108 | cknc icc0,cc7 | ||
109 | cstdu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
110 | csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3 | ||
111 | cstdu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
112 | beqlr icc3,#0 | ||
113 | |||
114 | # now do 8-byte remnant | ||
115 | subicc gr5,#8,gr0,icc1 | ||
116 | cknc icc1,cc7 | ||
117 | cstdu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
118 | csubcc gr5,gr7,gr5 ,cc7,#1 ; also set ICC3 | ||
119 | setlos.p #4,gr7 | ||
120 | beqlr icc3,#0 | ||
121 | |||
122 | # now do 4-byte remnant | ||
123 | subicc gr5,#4,gr0,icc0 | ||
124 | addi.p gr4,#4,gr4 | ||
125 | cknc icc0,cc7 | ||
126 | cstu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
127 | csubcc gr5,gr7,gr5 ,cc7,#1 ; also set ICC3 | ||
128 | subicc.p gr5,#2,gr0,icc1 | ||
129 | beqlr icc3,#0 | ||
130 | |||
131 | # now do 2-byte remnant | ||
132 | setlos #2,gr7 | ||
133 | addi.p gr4,#2,gr4 | ||
134 | cknc icc1,cc7 | ||
135 | csthu.p gr12,@(gr4,gr7) ,cc7,#1 | ||
136 | csubcc gr5,gr7,gr5 ,cc7,#1 ; also set ICC3 | ||
137 | subicc.p gr5,#1,gr0,icc0 | ||
138 | beqlr icc3,#0 | ||
139 | |||
140 | # now do 1-byte remnant | ||
141 | setlos #0,gr7 | ||
142 | addi.p gr4,#2,gr4 | ||
143 | cknc icc0,cc7 | ||
144 | cstb.p gr12,@(gr4,gr0) ,cc7,#1 | ||
145 | bralr | ||
146 | __memset_end: | ||
147 | |||
148 | .size memset, __memset_end-memset | ||
149 | |||
150 | ############################################################################### | ||
151 | # | ||
152 | # clear memory in userspace | ||
153 | # - return the number of bytes that could not be cleared (0 on complete success) | ||
154 | # | ||
155 | # long __memset_user(void *p, size_t count) | ||
156 | # | ||
157 | ############################################################################### | ||
158 | .globl __memset_user, __memset_user_error_lr, __memset_user_error_handler | ||
159 | .type __memset_user,@function | ||
160 | __memset_user: | ||
161 | movsg lr,gr11 | ||
162 | |||
163 | # abuse memset to do the dirty work | ||
164 | or.p gr9,gr9,gr10 | ||
165 | setlos #0,gr9 | ||
166 | call memset | ||
167 | __memset_user_error_lr: | ||
168 | jmpl.p @(gr11,gr0) | ||
169 | setlos #0,gr8 | ||
170 | |||
171 | # deal any exception generated by memset | ||
172 | # GR4 - memset's address tracking pointer | ||
173 | # GR7 - memset's step value (index register for store insns) | ||
174 | # GR8 - memset's original start address | ||
175 | # GR10 - memset's original count | ||
176 | __memset_user_error_handler: | ||
177 | add.p gr4,gr7,gr4 | ||
178 | add gr8,gr10,gr8 | ||
179 | jmpl.p @(gr11,gr0) | ||
180 | sub gr8,gr4,gr8 ; we return the amount left uncleared | ||
181 | |||
182 | .size __memset_user, .-__memset_user | ||
diff --git a/arch/frv/lib/outsl_ns.S b/arch/frv/lib/outsl_ns.S new file mode 100644 index 000000000000..4cd4c46a6966 --- /dev/null +++ b/arch/frv/lib/outsl_ns.S | |||
@@ -0,0 +1,59 @@ | |||
1 | /* outsl_ns.S: output array of 4b words to device without byte swapping | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | .text | ||
14 | .p2align 4 | ||
15 | |||
16 | ############################################################################### | ||
17 | # | ||
18 | # void __outsl_ns(unsigned int port, const void *buf, int n) | ||
19 | # | ||
20 | ############################################################################### | ||
21 | .globl __outsl_ns | ||
22 | .type __outsl_ns,@function | ||
23 | __outsl_ns: | ||
24 | andicc.p gr9,#3,gr0,icc0 | ||
25 | setlos #4,gr4 | ||
26 | bne icc0,#0,__outsl_ns_misaligned | ||
27 | subi gr9,#4,gr9 | ||
28 | 0: | ||
29 | ldu.p @(gr9,gr4),gr5 | ||
30 | subicc gr10,#1,gr10,icc0 | ||
31 | sti.p gr5,@(gr8,#0) | ||
32 | bhi icc0,#2,0b | ||
33 | |||
34 | membar | ||
35 | bralr | ||
36 | |||
37 | __outsl_ns_misaligned: | ||
38 | subi.p gr9,#1,gr9 | ||
39 | setlos #1,gr4 | ||
40 | 0: | ||
41 | ldubu @(gr9,gr4),gr5 | ||
42 | ldubu.p @(gr9,gr4),gr6 | ||
43 | slli gr5,#8,gr5 | ||
44 | ldubu.p @(gr9,gr4),gr7 | ||
45 | or gr5,gr6,gr5 | ||
46 | ldubu.p @(gr9,gr4),gr6 | ||
47 | slli gr5,#16,gr5 | ||
48 | slli.p gr7,#8,gr7 | ||
49 | or gr5,gr6,gr5 | ||
50 | subicc.p gr10,#1,gr10,icc0 | ||
51 | or gr5,gr7,gr5 | ||
52 | |||
53 | sti.p gr5,@(gr8,#0) | ||
54 | bhi icc0,#2,0b | ||
55 | |||
56 | membar | ||
57 | bralr | ||
58 | |||
59 | .size __outsl_ns, .-__outsl_ns | ||
diff --git a/arch/frv/lib/outsl_sw.S b/arch/frv/lib/outsl_sw.S new file mode 100644 index 000000000000..7eb56d35a956 --- /dev/null +++ b/arch/frv/lib/outsl_sw.S | |||
@@ -0,0 +1,45 @@ | |||
1 | /* outsl_ns.S: output array of 4b words to device with byte swapping | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | .text | ||
14 | .p2align 4 | ||
15 | |||
16 | ############################################################################### | ||
17 | # | ||
18 | # void __outsl_sw(unsigned int port, const void *buf, int n) | ||
19 | # | ||
20 | ############################################################################### | ||
21 | .globl __outsl_sw | ||
22 | .type __outsl_sw,@function | ||
23 | __outsl_sw: | ||
24 | subi.p gr9,#1,gr9 | ||
25 | setlos #1,gr4 | ||
26 | 0: | ||
27 | ldubu @(gr9,gr4),gr5 | ||
28 | ldubu @(gr9,gr4),gr6 | ||
29 | slli gr6,#8,gr6 | ||
30 | ldubu.p @(gr9,gr4),gr7 | ||
31 | or gr5,gr6,gr5 | ||
32 | ldubu.p @(gr9,gr4),gr6 | ||
33 | slli gr7,#16,gr7 | ||
34 | slli.p gr6,#24,gr6 | ||
35 | or gr5,gr7,gr5 | ||
36 | subicc.p gr10,#1,gr10,icc0 | ||
37 | or gr5,gr6,gr5 | ||
38 | |||
39 | sti.p gr5,@(gr8,#0) | ||
40 | bhi icc0,#2,0b | ||
41 | |||
42 | membar | ||
43 | bralr | ||
44 | |||
45 | .size __outsl_sw, .-__outsl_sw | ||