aboutsummaryrefslogtreecommitdiffstats
path: root/arch/c6x/lib
diff options
context:
space:
mode:
authorAurelien Jacquiot <a-jacquiot@ti.com>2011-10-04 11:15:51 -0400
committerMark Salter <msalter@redhat.com>2011-10-06 19:48:23 -0400
commit09831ca73443bd819ad7993db5409b19c899ba33 (patch)
tree4558fb0a5e0e1fcd8582be2155cd9c7498e429db /arch/c6x/lib
parenta7f626c1948ab6178d2338831c5ffea7385e9f7f (diff)
C6X: library code
Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter <msalter@redhat.com> Signed-off-by: Aurelien Jacquiot <a-jacquiot@ti.com> Signed-off-by: Mark Salter <msalter@redhat.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/c6x/lib')
-rw-r--r--arch/c6x/lib/checksum.c36
-rw-r--r--arch/c6x/lib/csum_64plus.S419
-rw-r--r--arch/c6x/lib/divi.S53
-rw-r--r--arch/c6x/lib/divremi.S46
-rw-r--r--arch/c6x/lib/divremu.S87
-rw-r--r--arch/c6x/lib/divu.S98
-rw-r--r--arch/c6x/lib/llshl.S37
-rw-r--r--arch/c6x/lib/llshr.S38
-rw-r--r--arch/c6x/lib/llshru.S38
-rw-r--r--arch/c6x/lib/memcpy_64plus.S46
-rw-r--r--arch/c6x/lib/mpyll.S49
-rw-r--r--arch/c6x/lib/negll.S31
-rw-r--r--arch/c6x/lib/pop_rts.S32
-rw-r--r--arch/c6x/lib/push_rts.S31
-rw-r--r--arch/c6x/lib/remi.S64
-rw-r--r--arch/c6x/lib/remu.S82
-rw-r--r--arch/c6x/lib/strasgi.S89
-rw-r--r--arch/c6x/lib/strasgi_64plus.S39
18 files changed, 1315 insertions, 0 deletions
diff --git a/arch/c6x/lib/checksum.c b/arch/c6x/lib/checksum.c
new file mode 100644
index 000000000000..67cc93b0b932
--- /dev/null
+++ b/arch/c6x/lib/checksum.c
@@ -0,0 +1,36 @@
1/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version
5 * 2 of the License, or (at your option) any later version.
6 */
7#include <linux/module.h>
8#include <net/checksum.h>
9
10#include <asm/byteorder.h>
11
12/*
13 * copy from fs while checksumming, otherwise like csum_partial
14 */
15__wsum
16csum_partial_copy_from_user(const void __user *src, void *dst, int len,
17 __wsum sum, int *csum_err)
18{
19 int missing;
20
21 missing = __copy_from_user(dst, src, len);
22 if (missing) {
23 memset(dst + len - missing, 0, missing);
24 *csum_err = -EFAULT;
25 } else
26 *csum_err = 0;
27
28 return csum_partial(dst, len, sum);
29}
30EXPORT_SYMBOL(csum_partial_copy_from_user);
31
32/* These are from csum_64plus.S */
33EXPORT_SYMBOL(csum_partial);
34EXPORT_SYMBOL(csum_partial_copy);
35EXPORT_SYMBOL(ip_compute_csum);
36EXPORT_SYMBOL(ip_fast_csum);
diff --git a/arch/c6x/lib/csum_64plus.S b/arch/c6x/lib/csum_64plus.S
new file mode 100644
index 000000000000..6d2589647227
--- /dev/null
+++ b/arch/c6x/lib/csum_64plus.S
@@ -0,0 +1,419 @@
1;
2; linux/arch/c6x/lib/csum_64plus.s
3;
4; Port on Texas Instruments TMS320C6x architecture
5;
6; Copyright (C) 2006, 2009, 2010, 2011 Texas Instruments Incorporated
7; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
8;
9; This program is free software; you can redistribute it and/or modify
10; it under the terms of the GNU General Public License version 2 as
11; published by the Free Software Foundation.
12;
13#include <linux/linkage.h>
14
15;
16;unsigned int csum_partial_copy(const char *src, char * dst,
17; int len, int sum)
18;
19; A4: src
20; B4: dst
21; A6: len
22; B6: sum
23; return csum in A4
24;
25
26 .text
27ENTRY(csum_partial_copy)
28 MVC .S2 ILC,B30
29
30 MV .D1X B6,A31 ; given csum
31 ZERO .D1 A9 ; csum (a side)
32|| ZERO .D2 B9 ; csum (b side)
33|| SHRU .S2X A6,2,B5 ; len / 4
34
35 ;; Check alignment and size
36 AND .S1 3,A4,A1
37|| AND .S2 3,B4,B0
38 OR .L2X B0,A1,B0 ; non aligned condition
39|| MVC .S2 B5,ILC
40|| MVK .D2 1,B2
41|| MV .D1X B5,A1 ; words condition
42 [!A1] B .S1 L8
43 [B0] BNOP .S1 L6,5
44
45 SPLOOP 1
46
47 ;; Main loop for aligned words
48 LDW .D1T1 *A4++,A7
49 NOP 4
50 MV .S2X A7,B7
51|| EXTU .S1 A7,0,16,A16
52 STW .D2T2 B7,*B4++
53|| MPYU .M2 B7,B2,B8
54|| ADD .L1 A16,A9,A9
55 NOP
56 SPKERNEL 8,0
57|| ADD .L2 B8,B9,B9
58
59 ZERO .D1 A1
60|| ADD .L1X A9,B9,A9 ; add csum from a and b sides
61
62L6:
63 [!A1] BNOP .S1 L8,5
64
65 ;; Main loop for non-aligned words
66 SPLOOP 2
67 || MVK .L1 1,A2
68
69 LDNW .D1T1 *A4++,A7
70 NOP 3
71
72 NOP
73 MV .S2X A7,B7
74 || EXTU .S1 A7,0,16,A16
75 || MPYU .M1 A7,A2,A8
76
77 ADD .L1 A16,A9,A9
78 SPKERNEL 6,0
79 || STNW .D2T2 B7,*B4++
80 || ADD .L1 A8,A9,A9
81
82L8: AND .S2X 2,A6,B5
83 CMPGT .L2 B5,0,B0
84 [!B0] BNOP .S1 L82,4
85
86 ;; Manage half-word
87 ZERO .L1 A7
88|| ZERO .D1 A8
89
90#ifdef CONFIG_CPU_BIG_ENDIAN
91
92 LDBU .D1T1 *A4++,A7
93 LDBU .D1T1 *A4++,A8
94 NOP 3
95 SHL .S1 A7,8,A0
96 ADD .S1 A8,A9,A9
97 STB .D2T1 A7,*B4++
98|| ADD .S1 A0,A9,A9
99 STB .D2T1 A8,*B4++
100
101#else
102
103 LDBU .D1T1 *A4++,A7
104 LDBU .D1T1 *A4++,A8
105 NOP 3
106 ADD .S1 A7,A9,A9
107 SHL .S1 A8,8,A0
108
109 STB .D2T1 A7,*B4++
110|| ADD .S1 A0,A9,A9
111 STB .D2T1 A8,*B4++
112
113#endif
114
115 ;; Manage eventually the last byte
116L82: AND .S2X 1,A6,B0
117 [!B0] BNOP .S1 L9,5
118
119|| ZERO .L1 A7
120
121L83: LDBU .D1T1 *A4++,A7
122 NOP 4
123
124 MV .L2X A7,B7
125
126#ifdef CONFIG_CPU_BIG_ENDIAN
127
128 STB .D2T2 B7,*B4++
129|| SHL .S1 A7,8,A7
130 ADD .S1 A7,A9,A9
131
132#else
133
134 STB .D2T2 B7,*B4++
135|| ADD .S1 A7,A9,A9
136
137#endif
138
139 ;; Fold the csum
140L9: SHRU .S2X A9,16,B0
141 [!B0] BNOP .S1 L10,5
142
143L91: SHRU .S2X A9,16,B4
144|| EXTU .S1 A9,16,16,A3
145 ADD .D1X A3,B4,A9
146
147 SHRU .S1 A9,16,A0
148 [A0] BNOP .S1 L91,5
149
150L10: ADD .D1 A31,A9,A9
151 MV .D1 A9,A4
152
153 BNOP .S2 B3,4
154 MVC .S2 B30,ILC
155ENDPROC(csum_partial_copy)
156
157;
158;unsigned short
159;ip_fast_csum(unsigned char *iph, unsigned int ihl)
160;{
161; unsigned int checksum = 0;
162; unsigned short *tosum = (unsigned short *) iph;
163; int len;
164;
165; len = ihl*4;
166;
167; if (len <= 0)
168; return 0;
169;
170; while(len) {
171; len -= 2;
172; checksum += *tosum++;
173; }
174; if (len & 1)
175; checksum += *(unsigned char*) tosum;
176;
177; while(checksum >> 16)
178; checksum = (checksum & 0xffff) + (checksum >> 16);
179;
180; return ~checksum;
181;}
182;
183; A4: iph
184; B4: ihl
185; return checksum in A4
186;
187 .text
188
189ENTRY(ip_fast_csum)
190 ZERO .D1 A5
191 || MVC .S2 ILC,B30
192 SHL .S2 B4,2,B0
193 CMPGT .L2 B0,0,B1
194 [!B1] BNOP .S1 L15,4
195 [!B1] ZERO .D1 A3
196
197 [!B0] B .S1 L12
198 SHRU .S2 B0,1,B0
199 MVC .S2 B0,ILC
200 NOP 3
201
202 SPLOOP 1
203 LDHU .D1T1 *A4++,A3
204 NOP 3
205 NOP
206 SPKERNEL 5,0
207 || ADD .L1 A3,A5,A5
208
209L12: SHRU .S1 A5,16,A0
210 [!A0] BNOP .S1 L14,5
211
212L13: SHRU .S2X A5,16,B4
213 EXTU .S1 A5,16,16,A3
214 ADD .D1X A3,B4,A5
215 SHRU .S1 A5,16,A0
216 [A0] BNOP .S1 L13,5
217
218L14: NOT .D1 A5,A3
219 EXTU .S1 A3,16,16,A3
220
221L15: BNOP .S2 B3,3
222 MVC .S2 B30,ILC
223 MV .D1 A3,A4
224ENDPROC(ip_fast_csum)
225
226;
227;unsigned short
228;do_csum(unsigned char *buff, unsigned int len)
229;{
230; int odd, count;
231; unsigned int result = 0;
232;
233; if (len <= 0)
234; goto out;
235; odd = 1 & (unsigned long) buff;
236; if (odd) {
237;#ifdef __LITTLE_ENDIAN
238; result += (*buff << 8);
239;#else
240; result = *buff;
241;#endif
242; len--;
243; buff++;
244; }
245; count = len >> 1; /* nr of 16-bit words.. */
246; if (count) {
247; if (2 & (unsigned long) buff) {
248; result += *(unsigned short *) buff;
249; count--;
250; len -= 2;
251; buff += 2;
252; }
253; count >>= 1; /* nr of 32-bit words.. */
254; if (count) {
255; unsigned int carry = 0;
256; do {
257; unsigned int w = *(unsigned int *) buff;
258; count--;
259; buff += 4;
260; result += carry;
261; result += w;
262; carry = (w > result);
263; } while (count);
264; result += carry;
265; result = (result & 0xffff) + (result >> 16);
266; }
267; if (len & 2) {
268; result += *(unsigned short *) buff;
269; buff += 2;
270; }
271; }
272; if (len & 1)
273;#ifdef __LITTLE_ENDIAN
274; result += *buff;
275;#else
276; result += (*buff << 8);
277;#endif
278; result = (result & 0xffff) + (result >> 16);
279; /* add up carry.. */
280; result = (result & 0xffff) + (result >> 16);
281; if (odd)
282; result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
283;out:
284; return result;
285;}
286;
287; A4: buff
288; B4: len
289; return checksum in A4
290;
291
292ENTRY(do_csum)
293 CMPGT .L2 B4,0,B0
294 [!B0] BNOP .S1 L26,3
295 EXTU .S1 A4,31,31,A0
296
297 MV .L1 A0,A3
298|| MV .S1X B3,A5
299|| MV .L2 B4,B3
300|| ZERO .D1 A1
301
302#ifdef CONFIG_CPU_BIG_ENDIAN
303 [A0] SUB .L2 B3,1,B3
304|| [A0] LDBU .D1T1 *A4++,A1
305#else
306 [!A0] BNOP .S1 L21,5
307|| [A0] LDBU .D1T1 *A4++,A0
308 SUB .L2 B3,1,B3
309|| SHL .S1 A0,8,A1
310L21:
311#endif
312 SHR .S2 B3,1,B0
313 [!B0] BNOP .S1 L24,3
314 MVK .L1 2,A0
315 AND .L1 A4,A0,A0
316
317 [!A0] BNOP .S1 L22,5
318|| [A0] LDHU .D1T1 *A4++,A0
319 SUB .L2 B0,1,B0
320|| SUB .S2 B3,2,B3
321|| ADD .L1 A0,A1,A1
322L22:
323 SHR .S2 B0,1,B0
324|| ZERO .L1 A0
325
326 [!B0] BNOP .S1 L23,5
327|| [B0] MVC .S2 B0,ILC
328
329 SPLOOP 3
330 SPMASK L1
331|| MV .L1 A1,A2
332|| LDW .D1T1 *A4++,A1
333
334 NOP 4
335 ADD .L1 A0,A1,A0
336 ADD .L1 A2,A0,A2
337
338 SPKERNEL 1,2
339|| CMPGTU .L1 A1,A2,A0
340
341 ADD .L1 A0,A2,A6
342 EXTU .S1 A6,16,16,A7
343 SHRU .S2X A6,16,B0
344 NOP 1
345 ADD .L1X A7,B0,A1
346L23:
347 MVK .L2 2,B0
348 AND .L2 B3,B0,B0
349 [B0] LDHU .D1T1 *A4++,A0
350 NOP 4
351 [B0] ADD .L1 A0,A1,A1
352L24:
353 EXTU .S2 B3,31,31,B0
354#ifdef CONFIG_CPU_BIG_ENDIAN
355 [!B0] BNOP .S1 L25,4
356|| [B0] LDBU .D1T1 *A4,A0
357 SHL .S1 A0,8,A0
358 ADD .L1 A0,A1,A1
359L25:
360#else
361 [B0] LDBU .D1T1 *A4,A0
362 NOP 4
363 [B0] ADD .L1 A0,A1,A1
364#endif
365 EXTU .S1 A1,16,16,A0
366 SHRU .S2X A1,16,B0
367 NOP 1
368 ADD .L1X A0,B0,A0
369 SHRU .S1 A0,16,A1
370 ADD .L1 A0,A1,A0
371 EXTU .S1 A0,16,16,A1
372 EXTU .S1 A1,16,24,A2
373
374 EXTU .S1 A1,24,16,A0
375|| MV .L2X A3,B0
376
377 [B0] OR .L1 A0,A2,A1
378L26:
379 NOP 1
380 BNOP .S2X A5,4
381 MV .L1 A1,A4
382ENDPROC(do_csum)
383
384;__wsum csum_partial(const void *buff, int len, __wsum wsum)
385;{
386; unsigned int sum = (__force unsigned int)wsum;
387; unsigned int result = do_csum(buff, len);
388;
389; /* add in old sum, and carry.. */
390; result += sum;
391; if (sum > result)
392; result += 1;
393; return (__force __wsum)result;
394;}
395;
396ENTRY(csum_partial)
397 MV .L1X B3,A9
398|| CALLP .S2 do_csum,B3
399|| MV .S1 A6,A8
400 BNOP .S2X A9,2
401 ADD .L1 A8,A4,A1
402 CMPGTU .L1 A8,A1,A0
403 ADD .L1 A1,A0,A4
404ENDPROC(csum_partial)
405
406;unsigned short
407;ip_compute_csum(unsigned char *buff, unsigned int len)
408;
409; A4: buff
410; B4: len
411; return checksum in A4
412
413ENTRY(ip_compute_csum)
414 MV .L1X B3,A9
415|| CALLP .S2 do_csum,B3
416 BNOP .S2X A9,3
417 NOT .S1 A4,A4
418 CLR .S1 A4,16,31,A4
419ENDPROC(ip_compute_csum)
diff --git a/arch/c6x/lib/divi.S b/arch/c6x/lib/divi.S
new file mode 100644
index 000000000000..4bde924f2a98
--- /dev/null
+++ b/arch/c6x/lib/divi.S
@@ -0,0 +1,53 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 ;; ABI considerations for the divide functions
21 ;; The following registers are call-used:
22 ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
23 ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
24 ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
25 ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
26 ;;
27 ;; In our implementation, divu and remu are leaf functions,
28 ;; while both divi and remi call into divu.
29 ;; A0 is not clobbered by any of the functions.
30 ;; divu does not clobber B2 either, which is taken advantage of
31 ;; in remi.
32 ;; divi uses B5 to hold the original return address during
33 ;; the call to divu.
34 ;; remi uses B2 and A5 to hold the input values during the
35 ;; call to divu. It stores B3 in on the stack.
36
37 .text
38ENTRY(__c6xabi_divi)
39 call .s2 __c6xabi_divu
40|| mv .d2 B3, B5
41|| cmpgt .l1 0, A4, A1
42|| cmpgt .l2 0, B4, B1
43
44 [A1] neg .l1 A4, A4
45|| [B1] neg .l2 B4, B4
46|| xor .s1x A1, B1, A1
47 [A1] addkpc .s2 _divu_ret, B3, 4
48_divu_ret:
49 neg .l1 A4, A4
50|| mv .l2 B3,B5
51|| ret .s2 B5
52 nop 5
53ENDPROC(__c6xabi_divi)
diff --git a/arch/c6x/lib/divremi.S b/arch/c6x/lib/divremi.S
new file mode 100644
index 000000000000..64bc5aa95ad3
--- /dev/null
+++ b/arch/c6x/lib/divremi.S
@@ -0,0 +1,46 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21ENTRY(__c6xabi_divremi)
22 stw .d2t2 B3, *B15--[2]
23|| cmpgt .l1 0, A4, A1
24|| cmpgt .l2 0, B4, B2
25|| mv .s1 A4, A5
26|| call .s2 __c6xabi_divu
27
28 [A1] neg .l1 A4, A4
29|| [B2] neg .l2 B4, B4
30|| xor .s2x B2, A1, B0
31|| mv .d2 B4, B2
32
33 [B0] addkpc .s2 _divu_ret_1, B3, 1
34 [!B0] addkpc .s2 _divu_ret_2, B3, 1
35 nop 2
36_divu_ret_1:
37 neg .l1 A4, A4
38_divu_ret_2:
39 ldw .d2t2 *++B15[2], B3
40
41 mpy32 .m1x A4, B2, A6
42 nop 3
43 ret .s2 B3
44 sub .l1 A5, A6, A5
45 nop 4
46ENDPROC(__c6xabi_divremi)
diff --git a/arch/c6x/lib/divremu.S b/arch/c6x/lib/divremu.S
new file mode 100644
index 000000000000..caa9f23ee167
--- /dev/null
+++ b/arch/c6x/lib/divremu.S
@@ -0,0 +1,87 @@
1;; Copyright 2011 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21ENTRY(__c6xabi_divremu)
22 ;; We use a series of up to 31 subc instructions. First, we find
23 ;; out how many leading zero bits there are in the divisor. This
24 ;; gives us both a shift count for aligning (shifting) the divisor
25 ;; to the, and the number of times we have to execute subc.
26
27 ;; At the end, we have both the remainder and most of the quotient
28 ;; in A4. The top bit of the quotient is computed first and is
29 ;; placed in A2.
30
31 ;; Return immediately if the dividend is zero. Setting B4 to 1
32 ;; is a trick to allow us to leave the following insns in the jump
33 ;; delay slot without affecting the result.
34 mv .s2x A4, B1
35
36 [b1] lmbd .l2 1, B4, B1
37||[!b1] b .s2 B3 ; RETURN A
38||[!b1] mvk .d2 1, B4
39
40||[!b1] zero .s1 A5
41 mv .l1x B1, A6
42|| shl .s2 B4, B1, B4
43
44 ;; The loop performs a maximum of 28 steps, so we do the
45 ;; first 3 here.
46 cmpltu .l1x A4, B4, A2
47 [!A2] sub .l1x A4, B4, A4
48|| shru .s2 B4, 1, B4
49|| xor .s1 1, A2, A2
50
51 shl .s1 A2, 31, A2
52|| [b1] subc .l1x A4,B4,A4
53|| [b1] add .s2 -1, B1, B1
54 [b1] subc .l1x A4,B4,A4
55|| [b1] add .s2 -1, B1, B1
56
57 ;; RETURN A may happen here (note: must happen before the next branch)
58__divremu0:
59 cmpgt .l2 B1, 7, B0
60|| [b1] subc .l1x A4,B4,A4
61|| [b1] add .s2 -1, B1, B1
62 [b1] subc .l1x A4,B4,A4
63|| [b1] add .s2 -1, B1, B1
64|| [b0] b .s1 __divremu0
65 [b1] subc .l1x A4,B4,A4
66|| [b1] add .s2 -1, B1, B1
67 [b1] subc .l1x A4,B4,A4
68|| [b1] add .s2 -1, B1, B1
69 [b1] subc .l1x A4,B4,A4
70|| [b1] add .s2 -1, B1, B1
71 [b1] subc .l1x A4,B4,A4
72|| [b1] add .s2 -1, B1, B1
73 [b1] subc .l1x A4,B4,A4
74|| [b1] add .s2 -1, B1, B1
75 ;; loop backwards branch happens here
76
77 ret .s2 B3
78|| mvk .s1 32, A1
79 sub .l1 A1, A6, A6
80|| extu .s1 A4, A6, A5
81 shl .s1 A4, A6, A4
82 shru .s1 A4, 1, A4
83|| sub .l1 A6, 1, A6
84 or .l1 A2, A4, A4
85 shru .s1 A4, A6, A4
86 nop
87ENDPROC(__c6xabi_divremu)
diff --git a/arch/c6x/lib/divu.S b/arch/c6x/lib/divu.S
new file mode 100644
index 000000000000..64af3c006dd3
--- /dev/null
+++ b/arch/c6x/lib/divu.S
@@ -0,0 +1,98 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 ;; ABI considerations for the divide functions
21 ;; The following registers are call-used:
22 ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
23 ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
24 ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
25 ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
26 ;;
27 ;; In our implementation, divu and remu are leaf functions,
28 ;; while both divi and remi call into divu.
29 ;; A0 is not clobbered by any of the functions.
30 ;; divu does not clobber B2 either, which is taken advantage of
31 ;; in remi.
32 ;; divi uses B5 to hold the original return address during
33 ;; the call to divu.
34 ;; remi uses B2 and A5 to hold the input values during the
35 ;; call to divu. It stores B3 in on the stack.
36
37 .text
38ENTRY(__c6xabi_divu)
39 ;; We use a series of up to 31 subc instructions. First, we find
40 ;; out how many leading zero bits there are in the divisor. This
41 ;; gives us both a shift count for aligning (shifting) the divisor
42 ;; to the, and the number of times we have to execute subc.
43
44 ;; At the end, we have both the remainder and most of the quotient
45 ;; in A4. The top bit of the quotient is computed first and is
46 ;; placed in A2.
47
48 ;; Return immediately if the dividend is zero.
49 mv .s2x A4, B1
50 [B1] lmbd .l2 1, B4, B1
51|| [!B1] b .s2 B3 ; RETURN A
52|| [!B1] mvk .d2 1, B4
53 mv .l1x B1, A6
54|| shl .s2 B4, B1, B4
55
56 ;; The loop performs a maximum of 28 steps, so we do the
57 ;; first 3 here.
58 cmpltu .l1x A4, B4, A2
59 [!A2] sub .l1x A4, B4, A4
60|| shru .s2 B4, 1, B4
61|| xor .s1 1, A2, A2
62
63 shl .s1 A2, 31, A2
64|| [B1] subc .l1x A4,B4,A4
65|| [B1] add .s2 -1, B1, B1
66 [B1] subc .l1x A4,B4,A4
67|| [B1] add .s2 -1, B1, B1
68
69 ;; RETURN A may happen here (note: must happen before the next branch)
70_divu_loop:
71 cmpgt .l2 B1, 7, B0
72|| [B1] subc .l1x A4,B4,A4
73|| [B1] add .s2 -1, B1, B1
74 [B1] subc .l1x A4,B4,A4
75|| [B1] add .s2 -1, B1, B1
76|| [B0] b .s1 _divu_loop
77 [B1] subc .l1x A4,B4,A4
78|| [B1] add .s2 -1, B1, B1
79 [B1] subc .l1x A4,B4,A4
80|| [B1] add .s2 -1, B1, B1
81 [B1] subc .l1x A4,B4,A4
82|| [B1] add .s2 -1, B1, B1
83 [B1] subc .l1x A4,B4,A4
84|| [B1] add .s2 -1, B1, B1
85 [B1] subc .l1x A4,B4,A4
86|| [B1] add .s2 -1, B1, B1
87 ;; loop backwards branch happens here
88
89 ret .s2 B3
90|| mvk .s1 32, A1
91 sub .l1 A1, A6, A6
92 shl .s1 A4, A6, A4
93 shru .s1 A4, 1, A4
94|| sub .l1 A6, 1, A6
95 or .l1 A2, A4, A4
96 shru .s1 A4, A6, A4
97 nop
98ENDPROC(__c6xabi_divu)
diff --git a/arch/c6x/lib/llshl.S b/arch/c6x/lib/llshl.S
new file mode 100644
index 000000000000..7b105e2d1b78
--- /dev/null
+++ b/arch/c6x/lib/llshl.S
@@ -0,0 +1,37 @@
1;; Copyright (C) 2010 Texas Instruments Incorporated
2;; Contributed by Mark Salter <msalter@redhat.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18;; uint64_t __c6xabi_llshl(uint64_t val, uint shift)
19
20#include <linux/linkage.h>
21
22 .text
23ENTRY(__c6xabi_llshl)
24 mv .l1x B4,A1
25 [!A1] b .s2 B3 ; just return if zero shift
26 mvk .s1 32,A0
27 sub .d1 A0,A1,A0
28 cmplt .l1 0,A0,A2
29 [A2] shru .s1 A4,A0,A0
30 [!A2] neg .l1 A0,A5
31|| [A2] shl .s1 A5,A1,A5
32 [!A2] shl .s1 A4,A5,A5
33|| [A2] or .d1 A5,A0,A5
34|| [!A2] mvk .l1 0,A4
35 [A2] shl .s1 A4,A1,A4
36 bnop .s2 B3,5
37ENDPROC(__c6xabi_llshl)
diff --git a/arch/c6x/lib/llshr.S b/arch/c6x/lib/llshr.S
new file mode 100644
index 000000000000..fde1bec7cf5a
--- /dev/null
+++ b/arch/c6x/lib/llshr.S
@@ -0,0 +1,38 @@
1;; Copyright (C) 2010 Texas Instruments Incorporated
2;; Contributed by Mark Salter <msalter@redhat.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18;; uint64_t __c6xabi_llshr(uint64_t val, uint shift)
19
20#include <linux/linkage.h>
21
22 .text
23ENTRY(__c6xabi_llshr)
24 mv .l1x B4,A1
25 [!A1] b .s2 B3 ; return if zero shift count
26 mvk .s1 32,A0
27 sub .d1 A0,A1,A0
28 cmplt .l1 0,A0,A2
29 [A2] shl .s1 A5,A0,A0
30 nop
31 [!A2] neg .l1 A0,A4
32|| [A2] shru .s1 A4,A1,A4
33 [!A2] shr .s1 A5,A4,A4
34|| [A2] or .d1 A4,A0,A4
35 [!A2] shr .s1 A5,0x1f,A5
36 [A2] shr .s1 A5,A1,A5
37 bnop .s2 B3,5
38ENDPROC(__c6xabi_llshr)
diff --git a/arch/c6x/lib/llshru.S b/arch/c6x/lib/llshru.S
new file mode 100644
index 000000000000..596ae3ff5c0f
--- /dev/null
+++ b/arch/c6x/lib/llshru.S
@@ -0,0 +1,38 @@
1;; Copyright (C) 2010 Texas Instruments Incorporated
2;; Contributed by Mark Salter <msalter@redhat.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18;; uint64_t __c6xabi_llshru(uint64_t val, uint shift)
19
20#include <linux/linkage.h>
21
22 .text
23ENTRY(__c6xabi_llshru)
24 mv .l1x B4,A1
25 [!A1] b .s2 B3 ; return if zero shift count
26 mvk .s1 32,A0
27 sub .d1 A0,A1,A0
28 cmplt .l1 0,A0,A2
29 [A2] shl .s1 A5,A0,A0
30 nop
31 [!A2] neg .l1 A0,A4
32|| [A2] shru .s1 A4,A1,A4
33 [!A2] shru .s1 A5,A4,A4
34|| [A2] or .d1 A4,A0,A4
35|| [!A2] mvk .l1 0,A5
36 [A2] shru .s1 A5,A1,A5
37 bnop .s2 B3,5
38ENDPROC(__c6xabi_llshru)
diff --git a/arch/c6x/lib/memcpy_64plus.S b/arch/c6x/lib/memcpy_64plus.S
new file mode 100644
index 000000000000..0bbc2cbf9318
--- /dev/null
+++ b/arch/c6x/lib/memcpy_64plus.S
@@ -0,0 +1,46 @@
1; Port on Texas Instruments TMS320C6x architecture
2;
3; Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
4; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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/linkage.h>
12
13 .text
14
15ENTRY(memcpy)
16 AND .L1 0x1,A6,A0
17 || AND .S1 0x2,A6,A1
18 || AND .L2X 0x4,A6,B0
19 || MV .D1 A4,A3
20 || MVC .S2 ILC,B2
21
22 [A0] LDB .D2T1 *B4++,A5
23 [A1] LDB .D2T1 *B4++,A7
24 [A1] LDB .D2T1 *B4++,A8
25 [B0] LDNW .D2T1 *B4++,A9
26 || SHRU .S2X A6,0x3,B1
27 [!B1] BNOP .S2 B3,1
28
29 [A0] STB .D1T1 A5,*A3++
30 ||[B1] MVC .S2 B1,ILC
31 [A1] STB .D1T1 A7,*A3++
32 [A1] STB .D1T1 A8,*A3++
33 [B0] STNW .D1T1 A9,*A3++ ; return when len < 8
34
35 SPLOOP 2
36
37 LDNDW .D2T1 *B4++,A9:A8
38 NOP 3
39
40 NOP
41 SPKERNEL 0,0
42 || STNDW .D1T1 A9:A8,*A3++
43
44 BNOP .S2 B3,4
45 MVC .S2 B2,ILC
46ENDPROC(memcpy)
diff --git a/arch/c6x/lib/mpyll.S b/arch/c6x/lib/mpyll.S
new file mode 100644
index 000000000000..f1034418b4db
--- /dev/null
+++ b/arch/c6x/lib/mpyll.S
@@ -0,0 +1,49 @@
1;; Copyright (C) 2010 Texas Instruments Incorporated
2;; Contributed by Mark Salter <msalter@redhat.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 ;; uint64_t __c6xabi_mpyll(uint64_t x, uint64_t y)
21 ;;
22 ;; 64x64 multiply
23 ;; First compute partial results using 32-bit parts of x and y:
24 ;;
25 ;; b63 b32 b31 b0
26 ;; -----------------------------
27 ;; | 1 | 0 |
28 ;; -----------------------------
29 ;;
30 ;; P0 = X0*Y0
31 ;; P1 = X0*Y1 + X1*Y0
32 ;; P2 = X1*Y1
33 ;;
34 ;; result = (P2 << 64) + (P1 << 32) + P0
35 ;;
36 ;; Since the result is also 64-bit, we can skip the P2 term.
37
38 .text
39ENTRY(__c6xabi_mpyll)
40 mpy32u .m1x A4,B4,A1:A0 ; X0*Y0
41 b .s2 B3
42 || mpy32u .m2x B5,A4,B1:B0 ; X0*Y1 (don't need upper 32-bits)
43 || mpy32u .m1x A5,B4,A3:A2 ; X1*Y0 (don't need upper 32-bits)
44 nop
45 nop
46 mv .s1 A0,A4
47 add .l1x A2,B0,A5
48 add .s1 A1,A5,A5
49ENDPROC(__c6xabi_mpyll)
diff --git a/arch/c6x/lib/negll.S b/arch/c6x/lib/negll.S
new file mode 100644
index 000000000000..82f4bcec9afb
--- /dev/null
+++ b/arch/c6x/lib/negll.S
@@ -0,0 +1,31 @@
1;; Copyright (C) 2010 Texas Instruments Incorporated
2;; Contributed by Mark Salter <msalter@redhat.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18;; int64_t __c6xabi_negll(int64_t val)
19
20#include <linux/linkage.h>
21
22 .text
23ENTRY(__c6xabi_negll)
24 b .s2 B3
25 mvk .l1 0,A0
26 subu .l1 A0,A4,A3:A2
27 sub .l1 A0,A5,A0
28|| ext .s1 A3,24,24,A5
29 add .l1 A5,A0,A5
30 mv .s1 A2,A4
31ENDPROC(__c6xabi_negll)
diff --git a/arch/c6x/lib/pop_rts.S b/arch/c6x/lib/pop_rts.S
new file mode 100644
index 000000000000..d7d96c70e9e7
--- /dev/null
+++ b/arch/c6x/lib/pop_rts.S
@@ -0,0 +1,32 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21
22ENTRY(__c6xabi_pop_rts)
23 lddw .d2t2 *++B15, B3:B2
24 lddw .d2t1 *++B15, A11:A10
25 lddw .d2t2 *++B15, B11:B10
26 lddw .d2t1 *++B15, A13:A12
27 lddw .d2t2 *++B15, B13:B12
28 lddw .d2t1 *++B15, A15:A14
29|| b .s2 B3
30 ldw .d2t2 *++B15[2], B14
31 nop 4
32ENDPROC(__c6xabi_pop_rts)
diff --git a/arch/c6x/lib/push_rts.S b/arch/c6x/lib/push_rts.S
new file mode 100644
index 000000000000..f6e3db3b6065
--- /dev/null
+++ b/arch/c6x/lib/push_rts.S
@@ -0,0 +1,31 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21
22ENTRY(__c6xabi_push_rts)
23 stw .d2t2 B14, *B15--[2]
24 stdw .d2t1 A15:A14, *B15--
25|| b .s2x A3
26 stdw .d2t2 B13:B12, *B15--
27 stdw .d2t1 A13:A12, *B15--
28 stdw .d2t2 B11:B10, *B15--
29 stdw .d2t1 A11:A10, *B15--
30 stdw .d2t2 B3:B2, *B15--
31ENDPROC(__c6xabi_push_rts)
diff --git a/arch/c6x/lib/remi.S b/arch/c6x/lib/remi.S
new file mode 100644
index 000000000000..6f2ca18c3f98
--- /dev/null
+++ b/arch/c6x/lib/remi.S
@@ -0,0 +1,64 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 ;; ABI considerations for the divide functions
21 ;; The following registers are call-used:
22 ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
23 ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
24 ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
25 ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
26 ;;
27 ;; In our implementation, divu and remu are leaf functions,
28 ;; while both divi and remi call into divu.
29 ;; A0 is not clobbered by any of the functions.
30 ;; divu does not clobber B2 either, which is taken advantage of
31 ;; in remi.
32 ;; divi uses B5 to hold the original return address during
33 ;; the call to divu.
34 ;; remi uses B2 and A5 to hold the input values during the
35 ;; call to divu. It stores B3 in on the stack.
36
37 .text
38
39ENTRY(__c6xabi_remi)
40 stw .d2t2 B3, *B15--[2]
41|| cmpgt .l1 0, A4, A1
42|| cmpgt .l2 0, B4, B2
43|| mv .s1 A4, A5
44|| call .s2 __c6xabi_divu
45
46 [A1] neg .l1 A4, A4
47|| [B2] neg .l2 B4, B4
48|| xor .s2x B2, A1, B0
49|| mv .d2 B4, B2
50
51 [B0] addkpc .s2 _divu_ret_1, B3, 1
52 [!B0] addkpc .s2 _divu_ret_2, B3, 1
53 nop 2
54_divu_ret_1:
55 neg .l1 A4, A4
56_divu_ret_2:
57 ldw .d2t2 *++B15[2], B3
58
59 mpy32 .m1x A4, B2, A6
60 nop 3
61 ret .s2 B3
62 sub .l1 A5, A6, A4
63 nop 4
64ENDPROC(__c6xabi_remi)
diff --git a/arch/c6x/lib/remu.S b/arch/c6x/lib/remu.S
new file mode 100644
index 000000000000..3fae719185ab
--- /dev/null
+++ b/arch/c6x/lib/remu.S
@@ -0,0 +1,82 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 ;; ABI considerations for the divide functions
21 ;; The following registers are call-used:
22 ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
23 ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
24 ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
25 ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
26 ;;
27 ;; In our implementation, divu and remu are leaf functions,
28 ;; while both divi and remi call into divu.
29 ;; A0 is not clobbered by any of the functions.
30 ;; divu does not clobber B2 either, which is taken advantage of
31 ;; in remi.
32 ;; divi uses B5 to hold the original return address during
33 ;; the call to divu.
34 ;; remi uses B2 and A5 to hold the input values during the
35 ;; call to divu. It stores B3 in on the stack.
36
37
38 .text
39
40ENTRY(__c6xabi_remu)
41 ;; The ABI seems designed to prevent these functions calling each other,
42 ;; so we duplicate most of the divsi3 code here.
43 mv .s2x A4, B1
44 lmbd .l2 1, B4, B1
45|| [!B1] b .s2 B3 ; RETURN A
46|| [!B1] mvk .d2 1, B4
47
48 mv .l1x B1, A7
49|| shl .s2 B4, B1, B4
50
51 cmpltu .l1x A4, B4, A1
52 [!A1] sub .l1x A4, B4, A4
53 shru .s2 B4, 1, B4
54
55_remu_loop:
56 cmpgt .l2 B1, 7, B0
57|| [B1] subc .l1x A4,B4,A4
58|| [B1] add .s2 -1, B1, B1
59 ;; RETURN A may happen here (note: must happen before the next branch)
60 [B1] subc .l1x A4,B4,A4
61|| [B1] add .s2 -1, B1, B1
62|| [B0] b .s1 _remu_loop
63 [B1] subc .l1x A4,B4,A4
64|| [B1] add .s2 -1, B1, B1
65 [B1] subc .l1x A4,B4,A4
66|| [B1] add .s2 -1, B1, B1
67 [B1] subc .l1x A4,B4,A4
68|| [B1] add .s2 -1, B1, B1
69 [B1] subc .l1x A4,B4,A4
70|| [B1] add .s2 -1, B1, B1
71 [B1] subc .l1x A4,B4,A4
72|| [B1] add .s2 -1, B1, B1
73 ;; loop backwards branch happens here
74
75 ret .s2 B3
76 [B1] subc .l1x A4,B4,A4
77|| [B1] add .s2 -1, B1, B1
78 [B1] subc .l1x A4,B4,A4
79
80 extu .s1 A4, A7, A4
81 nop 2
82ENDPROC(__c6xabi_remu)
diff --git a/arch/c6x/lib/strasgi.S b/arch/c6x/lib/strasgi.S
new file mode 100644
index 000000000000..de2740765536
--- /dev/null
+++ b/arch/c6x/lib/strasgi.S
@@ -0,0 +1,89 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21
22ENTRY(__c6xabi_strasgi)
23 ;; This is essentially memcpy, with alignment known to be at least
24 ;; 4, and the size a multiple of 4 greater than or equal to 28.
25 ldw .d2t1 *B4++, A0
26|| mvk .s2 16, B1
27 ldw .d2t1 *B4++, A1
28|| mvk .s2 20, B2
29|| sub .d1 A6, 24, A6
30 ldw .d2t1 *B4++, A5
31 ldw .d2t1 *B4++, A7
32|| mv .l2x A6, B7
33 ldw .d2t1 *B4++, A8
34 ldw .d2t1 *B4++, A9
35|| mv .s2x A0, B5
36|| cmpltu .l2 B2, B7, B0
37
38_strasgi_loop:
39 stw .d1t2 B5, *A4++
40|| [B0] ldw .d2t1 *B4++, A0
41|| mv .s2x A1, B5
42|| mv .l2 B7, B6
43
44 [B0] sub .d2 B6, 24, B7
45|| [B0] b .s2 _strasgi_loop
46|| cmpltu .l2 B1, B6, B0
47
48 [B0] ldw .d2t1 *B4++, A1
49|| stw .d1t2 B5, *A4++
50|| mv .s2x A5, B5
51|| cmpltu .l2 12, B6, B0
52
53 [B0] ldw .d2t1 *B4++, A5
54|| stw .d1t2 B5, *A4++
55|| mv .s2x A7, B5
56|| cmpltu .l2 8, B6, B0
57
58 [B0] ldw .d2t1 *B4++, A7
59|| stw .d1t2 B5, *A4++
60|| mv .s2x A8, B5
61|| cmpltu .l2 4, B6, B0
62
63 [B0] ldw .d2t1 *B4++, A8
64|| stw .d1t2 B5, *A4++
65|| mv .s2x A9, B5
66|| cmpltu .l2 0, B6, B0
67
68 [B0] ldw .d2t1 *B4++, A9
69|| stw .d1t2 B5, *A4++
70|| mv .s2x A0, B5
71|| cmpltu .l2 B2, B7, B0
72
73 ;; loop back branch happens here
74
75 cmpltu .l2 B1, B6, B0
76|| ret .s2 b3
77
78 [B0] stw .d1t1 A1, *A4++
79|| cmpltu .l2 12, B6, B0
80 [B0] stw .d1t1 A5, *A4++
81|| cmpltu .l2 8, B6, B0
82 [B0] stw .d1t1 A7, *A4++
83|| cmpltu .l2 4, B6, B0
84 [B0] stw .d1t1 A8, *A4++
85|| cmpltu .l2 0, B6, B0
86 [B0] stw .d1t1 A9, *A4++
87
88 ;; return happens here
89ENDPROC(__c6xabi_strasgi)
diff --git a/arch/c6x/lib/strasgi_64plus.S b/arch/c6x/lib/strasgi_64plus.S
new file mode 100644
index 000000000000..c9fd159b5fa2
--- /dev/null
+++ b/arch/c6x/lib/strasgi_64plus.S
@@ -0,0 +1,39 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21
22ENTRY(__c6xabi_strasgi_64plus)
23 shru .s2x a6, 2, b31
24|| mv .s1 a4, a30
25|| mv .d2 b4, b30
26
27 add .s2 -4, b31, b31
28
29 sploopd 1
30|| mvc .s2 b31, ilc
31 ldw .d2t2 *b30++, b31
32 nop 4
33 mv .s1x b31,a31
34 spkernel 6, 0
35|| stw .d1t1 a31, *a30++
36
37 ret .s2 b3
38 nop 5
39ENDPROC(__c6xabi_strasgi_64plus)