diff options
Diffstat (limited to 'arch/parisc/lib/libgcc')
-rw-r--r-- | arch/parisc/lib/libgcc/Makefile | 4 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__ashldi3.c | 19 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__ashrdi3.c | 19 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__clzsi2.c | 30 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__divdi3.c | 23 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__divsi3.c | 23 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__lshrdi3.c | 19 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__moddi3.c | 23 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__modsi3.c | 23 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__muldi3.c | 22 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__udivdi3.c | 7 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__udivmoddi4.c | 31 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__udivmodsi4.c | 31 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__udivsi3.c | 7 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__umoddi3.c | 10 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__umodsi3.c | 10 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/__umulsidi3.c | 46 | ||||
-rw-r--r-- | arch/parisc/lib/libgcc/libgcc.h | 32 |
18 files changed, 379 insertions, 0 deletions
diff --git a/arch/parisc/lib/libgcc/Makefile b/arch/parisc/lib/libgcc/Makefile new file mode 100644 index 000000000000..b67a85ad9c87 --- /dev/null +++ b/arch/parisc/lib/libgcc/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | obj-y := __ashldi3.o __ashrdi3.o __clzsi2.o __divdi3.o __divsi3.o \ | ||
2 | __lshrdi3.o __moddi3.o __modsi3.o __udivdi3.o \ | ||
3 | __udivmoddi4.o __udivmodsi4.o __udivsi3.o \ | ||
4 | __umoddi3.o __umodsi3.o __muldi3.o __umulsidi3.o | ||
diff --git a/arch/parisc/lib/libgcc/__ashldi3.c b/arch/parisc/lib/libgcc/__ashldi3.c new file mode 100644 index 000000000000..a14a257abb2b --- /dev/null +++ b/arch/parisc/lib/libgcc/__ashldi3.c | |||
@@ -0,0 +1,19 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | u64 __ashldi3(u64 v, int cnt) | ||
4 | { | ||
5 | int c = cnt & 31; | ||
6 | u32 vl = (u32) v; | ||
7 | u32 vh = (u32) (v >> 32); | ||
8 | |||
9 | if (cnt & 32) { | ||
10 | vh = (vl << c); | ||
11 | vl = 0; | ||
12 | } else { | ||
13 | vh = (vh << c) + (vl >> (32 - c)); | ||
14 | vl = (vl << c); | ||
15 | } | ||
16 | |||
17 | return ((u64) vh << 32) + vl; | ||
18 | } | ||
19 | EXPORT_SYMBOL(__ashldi3); | ||
diff --git a/arch/parisc/lib/libgcc/__ashrdi3.c b/arch/parisc/lib/libgcc/__ashrdi3.c new file mode 100644 index 000000000000..8636a5aa4f77 --- /dev/null +++ b/arch/parisc/lib/libgcc/__ashrdi3.c | |||
@@ -0,0 +1,19 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | u64 __ashrdi3(u64 v, int cnt) | ||
4 | { | ||
5 | int c = cnt & 31; | ||
6 | u32 vl = (u32) v; | ||
7 | u32 vh = (u32) (v >> 32); | ||
8 | |||
9 | if (cnt & 32) { | ||
10 | vl = ((s32) vh >> c); | ||
11 | vh = (s32) vh >> 31; | ||
12 | } else { | ||
13 | vl = (vl >> c) + (vh << (32 - c)); | ||
14 | vh = ((s32) vh >> c); | ||
15 | } | ||
16 | |||
17 | return ((u64) vh << 32) + vl; | ||
18 | } | ||
19 | EXPORT_SYMBOL(__ashrdi3); | ||
diff --git a/arch/parisc/lib/libgcc/__clzsi2.c b/arch/parisc/lib/libgcc/__clzsi2.c new file mode 100644 index 000000000000..a7aa2f55a9c6 --- /dev/null +++ b/arch/parisc/lib/libgcc/__clzsi2.c | |||
@@ -0,0 +1,30 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | u32 __clzsi2(u32 v) | ||
4 | { | ||
5 | int p = 31; | ||
6 | |||
7 | if (v & 0xffff0000) { | ||
8 | p -= 16; | ||
9 | v >>= 16; | ||
10 | } | ||
11 | if (v & 0xff00) { | ||
12 | p -= 8; | ||
13 | v >>= 8; | ||
14 | } | ||
15 | if (v & 0xf0) { | ||
16 | p -= 4; | ||
17 | v >>= 4; | ||
18 | } | ||
19 | if (v & 0xc) { | ||
20 | p -= 2; | ||
21 | v >>= 2; | ||
22 | } | ||
23 | if (v & 0x2) { | ||
24 | p -= 1; | ||
25 | v >>= 1; | ||
26 | } | ||
27 | |||
28 | return p; | ||
29 | } | ||
30 | EXPORT_SYMBOL(__clzsi2); | ||
diff --git a/arch/parisc/lib/libgcc/__divdi3.c b/arch/parisc/lib/libgcc/__divdi3.c new file mode 100644 index 000000000000..f23c6fe2838b --- /dev/null +++ b/arch/parisc/lib/libgcc/__divdi3.c | |||
@@ -0,0 +1,23 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | s64 __divdi3(s64 num, s64 den) | ||
4 | { | ||
5 | int minus = 0; | ||
6 | s64 v; | ||
7 | |||
8 | if (num < 0) { | ||
9 | num = -num; | ||
10 | minus = 1; | ||
11 | } | ||
12 | if (den < 0) { | ||
13 | den = -den; | ||
14 | minus ^= 1; | ||
15 | } | ||
16 | |||
17 | v = __udivmoddi4(num, den, NULL); | ||
18 | if (minus) | ||
19 | v = -v; | ||
20 | |||
21 | return v; | ||
22 | } | ||
23 | EXPORT_SYMBOL(__divdi3); | ||
diff --git a/arch/parisc/lib/libgcc/__divsi3.c b/arch/parisc/lib/libgcc/__divsi3.c new file mode 100644 index 000000000000..730fb530680d --- /dev/null +++ b/arch/parisc/lib/libgcc/__divsi3.c | |||
@@ -0,0 +1,23 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | s32 __divsi3(s32 num, s32 den) | ||
4 | { | ||
5 | int minus = 0; | ||
6 | s32 v; | ||
7 | |||
8 | if (num < 0) { | ||
9 | num = -num; | ||
10 | minus = 1; | ||
11 | } | ||
12 | if (den < 0) { | ||
13 | den = -den; | ||
14 | minus ^= 1; | ||
15 | } | ||
16 | |||
17 | v = __udivmodsi4(num, den, NULL); | ||
18 | if (minus) | ||
19 | v = -v; | ||
20 | |||
21 | return v; | ||
22 | } | ||
23 | EXPORT_SYMBOL(__divsi3); | ||
diff --git a/arch/parisc/lib/libgcc/__lshrdi3.c b/arch/parisc/lib/libgcc/__lshrdi3.c new file mode 100644 index 000000000000..4a820708ec57 --- /dev/null +++ b/arch/parisc/lib/libgcc/__lshrdi3.c | |||
@@ -0,0 +1,19 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | u64 __lshrdi3(u64 v, int cnt) | ||
4 | { | ||
5 | int c = cnt & 31; | ||
6 | u32 vl = (u32) v; | ||
7 | u32 vh = (u32) (v >> 32); | ||
8 | |||
9 | if (cnt & 32) { | ||
10 | vl = (vh >> c); | ||
11 | vh = 0; | ||
12 | } else { | ||
13 | vl = (vl >> c) + (vh << (32 - c)); | ||
14 | vh = (vh >> c); | ||
15 | } | ||
16 | |||
17 | return ((u64) vh << 32) + vl; | ||
18 | } | ||
19 | EXPORT_SYMBOL(__lshrdi3); | ||
diff --git a/arch/parisc/lib/libgcc/__moddi3.c b/arch/parisc/lib/libgcc/__moddi3.c new file mode 100644 index 000000000000..ed64bbafc989 --- /dev/null +++ b/arch/parisc/lib/libgcc/__moddi3.c | |||
@@ -0,0 +1,23 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | s64 __moddi3(s64 num, s64 den) | ||
4 | { | ||
5 | int minus = 0; | ||
6 | s64 v; | ||
7 | |||
8 | if (num < 0) { | ||
9 | num = -num; | ||
10 | minus = 1; | ||
11 | } | ||
12 | if (den < 0) { | ||
13 | den = -den; | ||
14 | minus ^= 1; | ||
15 | } | ||
16 | |||
17 | (void)__udivmoddi4(num, den, (u64 *) & v); | ||
18 | if (minus) | ||
19 | v = -v; | ||
20 | |||
21 | return v; | ||
22 | } | ||
23 | EXPORT_SYMBOL(__moddi3); | ||
diff --git a/arch/parisc/lib/libgcc/__modsi3.c b/arch/parisc/lib/libgcc/__modsi3.c new file mode 100644 index 000000000000..62f773efaeea --- /dev/null +++ b/arch/parisc/lib/libgcc/__modsi3.c | |||
@@ -0,0 +1,23 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | s32 __modsi3(s32 num, s32 den) | ||
4 | { | ||
5 | int minus = 0; | ||
6 | s32 v; | ||
7 | |||
8 | if (num < 0) { | ||
9 | num = -num; | ||
10 | minus = 1; | ||
11 | } | ||
12 | if (den < 0) { | ||
13 | den = -den; | ||
14 | minus ^= 1; | ||
15 | } | ||
16 | |||
17 | (void)__udivmodsi4(num, den, (u32 *) & v); | ||
18 | if (minus) | ||
19 | v = -v; | ||
20 | |||
21 | return v; | ||
22 | } | ||
23 | EXPORT_SYMBOL(__modsi3); | ||
diff --git a/arch/parisc/lib/libgcc/__muldi3.c b/arch/parisc/lib/libgcc/__muldi3.c new file mode 100644 index 000000000000..3308abdd5580 --- /dev/null +++ b/arch/parisc/lib/libgcc/__muldi3.c | |||
@@ -0,0 +1,22 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | union DWunion { | ||
4 | struct { | ||
5 | s32 high; | ||
6 | s32 low; | ||
7 | } s; | ||
8 | s64 ll; | ||
9 | }; | ||
10 | |||
11 | s64 __muldi3(s64 u, s64 v) | ||
12 | { | ||
13 | const union DWunion uu = { .ll = u }; | ||
14 | const union DWunion vv = { .ll = v }; | ||
15 | union DWunion w = { .ll = __umulsidi3(uu.s.low, vv.s.low) }; | ||
16 | |||
17 | w.s.high += ((u32)uu.s.low * (u32)vv.s.high | ||
18 | + (u32)uu.s.high * (u32)vv.s.low); | ||
19 | |||
20 | return w.ll; | ||
21 | } | ||
22 | EXPORT_SYMBOL(__muldi3); | ||
diff --git a/arch/parisc/lib/libgcc/__udivdi3.c b/arch/parisc/lib/libgcc/__udivdi3.c new file mode 100644 index 000000000000..740023d690f5 --- /dev/null +++ b/arch/parisc/lib/libgcc/__udivdi3.c | |||
@@ -0,0 +1,7 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | u64 __udivdi3(u64 num, u64 den) | ||
4 | { | ||
5 | return __udivmoddi4(num, den, NULL); | ||
6 | } | ||
7 | EXPORT_SYMBOL(__udivdi3); | ||
diff --git a/arch/parisc/lib/libgcc/__udivmoddi4.c b/arch/parisc/lib/libgcc/__udivmoddi4.c new file mode 100644 index 000000000000..2df0caa5a7d8 --- /dev/null +++ b/arch/parisc/lib/libgcc/__udivmoddi4.c | |||
@@ -0,0 +1,31 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | u64 __udivmoddi4(u64 num, u64 den, u64 * rem_p) | ||
4 | { | ||
5 | u64 quot = 0, qbit = 1; | ||
6 | |||
7 | if (den == 0) { | ||
8 | BUG(); | ||
9 | } | ||
10 | |||
11 | /* Left-justify denominator and count shift */ | ||
12 | while ((s64) den >= 0) { | ||
13 | den <<= 1; | ||
14 | qbit <<= 1; | ||
15 | } | ||
16 | |||
17 | while (qbit) { | ||
18 | if (den <= num) { | ||
19 | num -= den; | ||
20 | quot += qbit; | ||
21 | } | ||
22 | den >>= 1; | ||
23 | qbit >>= 1; | ||
24 | } | ||
25 | |||
26 | if (rem_p) | ||
27 | *rem_p = num; | ||
28 | |||
29 | return quot; | ||
30 | } | ||
31 | EXPORT_SYMBOL(__udivmoddi4); | ||
diff --git a/arch/parisc/lib/libgcc/__udivmodsi4.c b/arch/parisc/lib/libgcc/__udivmodsi4.c new file mode 100644 index 000000000000..2a2fc28b2026 --- /dev/null +++ b/arch/parisc/lib/libgcc/__udivmodsi4.c | |||
@@ -0,0 +1,31 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | u32 __udivmodsi4(u32 num, u32 den, u32 * rem_p) | ||
4 | { | ||
5 | u32 quot = 0, qbit = 1; | ||
6 | |||
7 | if (den == 0) { | ||
8 | BUG(); | ||
9 | } | ||
10 | |||
11 | /* Left-justify denominator and count shift */ | ||
12 | while ((s32) den >= 0) { | ||
13 | den <<= 1; | ||
14 | qbit <<= 1; | ||
15 | } | ||
16 | |||
17 | while (qbit) { | ||
18 | if (den <= num) { | ||
19 | num -= den; | ||
20 | quot += qbit; | ||
21 | } | ||
22 | den >>= 1; | ||
23 | qbit >>= 1; | ||
24 | } | ||
25 | |||
26 | if (rem_p) | ||
27 | *rem_p = num; | ||
28 | |||
29 | return quot; | ||
30 | } | ||
31 | EXPORT_SYMBOL(__udivmodsi4); | ||
diff --git a/arch/parisc/lib/libgcc/__udivsi3.c b/arch/parisc/lib/libgcc/__udivsi3.c new file mode 100644 index 000000000000..756a44164e90 --- /dev/null +++ b/arch/parisc/lib/libgcc/__udivsi3.c | |||
@@ -0,0 +1,7 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | u32 __udivsi3(u32 num, u32 den) | ||
4 | { | ||
5 | return __udivmodsi4(num, den, NULL); | ||
6 | } | ||
7 | EXPORT_SYMBOL(__udivsi3); | ||
diff --git a/arch/parisc/lib/libgcc/__umoddi3.c b/arch/parisc/lib/libgcc/__umoddi3.c new file mode 100644 index 000000000000..ac744e948bc1 --- /dev/null +++ b/arch/parisc/lib/libgcc/__umoddi3.c | |||
@@ -0,0 +1,10 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | u64 __umoddi3(u64 num, u64 den) | ||
4 | { | ||
5 | u64 v; | ||
6 | |||
7 | (void)__udivmoddi4(num, den, &v); | ||
8 | return v; | ||
9 | } | ||
10 | EXPORT_SYMBOL(__umoddi3); | ||
diff --git a/arch/parisc/lib/libgcc/__umodsi3.c b/arch/parisc/lib/libgcc/__umodsi3.c new file mode 100644 index 000000000000..51f55aa89f9a --- /dev/null +++ b/arch/parisc/lib/libgcc/__umodsi3.c | |||
@@ -0,0 +1,10 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | u32 __umodsi3(u32 num, u32 den) | ||
4 | { | ||
5 | u32 v; | ||
6 | |||
7 | (void)__udivmodsi4(num, den, &v); | ||
8 | return v; | ||
9 | } | ||
10 | EXPORT_SYMBOL(__umodsi3); | ||
diff --git a/arch/parisc/lib/libgcc/__umulsidi3.c b/arch/parisc/lib/libgcc/__umulsidi3.c new file mode 100644 index 000000000000..396f669164d4 --- /dev/null +++ b/arch/parisc/lib/libgcc/__umulsidi3.c | |||
@@ -0,0 +1,46 @@ | |||
1 | #include "libgcc.h" | ||
2 | |||
3 | #define __ll_B ((u32) 1 << (32 / 2)) | ||
4 | #define __ll_lowpart(t) ((u32) (t) & (__ll_B - 1)) | ||
5 | #define __ll_highpart(t) ((u32) (t) >> 16) | ||
6 | |||
7 | #define umul_ppmm(w1, w0, u, v) \ | ||
8 | do { \ | ||
9 | u32 __x0, __x1, __x2, __x3; \ | ||
10 | u16 __ul, __vl, __uh, __vh; \ | ||
11 | \ | ||
12 | __ul = __ll_lowpart (u); \ | ||
13 | __uh = __ll_highpart (u); \ | ||
14 | __vl = __ll_lowpart (v); \ | ||
15 | __vh = __ll_highpart (v); \ | ||
16 | \ | ||
17 | __x0 = (u32) __ul * __vl; \ | ||
18 | __x1 = (u32) __ul * __vh; \ | ||
19 | __x2 = (u32) __uh * __vl; \ | ||
20 | __x3 = (u32) __uh * __vh; \ | ||
21 | \ | ||
22 | __x1 += __ll_highpart (__x0);/* this can't give carry */ \ | ||
23 | __x1 += __x2; /* but this indeed can */ \ | ||
24 | if (__x1 < __x2) /* did we get it? */ \ | ||
25 | __x3 += __ll_B; /* yes, add it in the proper pos. */ \ | ||
26 | \ | ||
27 | (w1) = __x3 + __ll_highpart (__x1); \ | ||
28 | (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ | ||
29 | } while (0) | ||
30 | |||
31 | union DWunion { | ||
32 | struct { | ||
33 | s32 high; | ||
34 | s32 low; | ||
35 | } s; | ||
36 | s64 ll; | ||
37 | }; | ||
38 | |||
39 | u64 __umulsidi3(u32 u, u32 v) | ||
40 | { | ||
41 | union DWunion __w; | ||
42 | |||
43 | umul_ppmm(__w.s.high, __w.s.low, u, v); | ||
44 | |||
45 | return __w.ll; | ||
46 | } | ||
diff --git a/arch/parisc/lib/libgcc/libgcc.h b/arch/parisc/lib/libgcc/libgcc.h new file mode 100644 index 000000000000..5a6f7a510fbd --- /dev/null +++ b/arch/parisc/lib/libgcc/libgcc.h | |||
@@ -0,0 +1,32 @@ | |||
1 | #ifndef _PA_LIBGCC_H_ | ||
2 | #define _PA_LIBGCC_H_ | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | #include <linux/module.h> | ||
6 | |||
7 | /* Cribbed from klibc/libgcc/ */ | ||
8 | u64 __ashldi3(u64 v, int cnt); | ||
9 | u64 __ashrdi3(u64 v, int cnt); | ||
10 | |||
11 | u32 __clzsi2(u32 v); | ||
12 | |||
13 | s64 __divdi3(s64 num, s64 den); | ||
14 | s32 __divsi3(s32 num, s32 den); | ||
15 | |||
16 | u64 __lshrdi3(u64 v, int cnt); | ||
17 | |||
18 | s64 __moddi3(s64 num, s64 den); | ||
19 | s32 __modsi3(s32 num, s32 den); | ||
20 | |||
21 | u64 __udivdi3(u64 num, u64 den); | ||
22 | u32 __udivsi3(u32 num, u32 den); | ||
23 | |||
24 | u64 __udivmoddi4(u64 num, u64 den, u64 * rem_p); | ||
25 | u32 __udivmodsi4(u32 num, u32 den, u32 * rem_p); | ||
26 | |||
27 | u64 __umulsidi3(u32 u, u32 v); | ||
28 | |||
29 | u64 __umoddi3(u64 num, u64 den); | ||
30 | u32 __umodsi3(u32 num, u32 den); | ||
31 | |||
32 | #endif /*_PA_LIBGCC_H_*/ | ||