aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/lib/libgcc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/lib/libgcc')
-rw-r--r--arch/parisc/lib/libgcc/Makefile4
-rw-r--r--arch/parisc/lib/libgcc/__ashldi3.c19
-rw-r--r--arch/parisc/lib/libgcc/__ashrdi3.c19
-rw-r--r--arch/parisc/lib/libgcc/__clzsi2.c30
-rw-r--r--arch/parisc/lib/libgcc/__divdi3.c23
-rw-r--r--arch/parisc/lib/libgcc/__divsi3.c23
-rw-r--r--arch/parisc/lib/libgcc/__lshrdi3.c19
-rw-r--r--arch/parisc/lib/libgcc/__moddi3.c23
-rw-r--r--arch/parisc/lib/libgcc/__modsi3.c23
-rw-r--r--arch/parisc/lib/libgcc/__muldi3.c22
-rw-r--r--arch/parisc/lib/libgcc/__udivdi3.c7
-rw-r--r--arch/parisc/lib/libgcc/__udivmoddi4.c31
-rw-r--r--arch/parisc/lib/libgcc/__udivmodsi4.c31
-rw-r--r--arch/parisc/lib/libgcc/__udivsi3.c7
-rw-r--r--arch/parisc/lib/libgcc/__umoddi3.c10
-rw-r--r--arch/parisc/lib/libgcc/__umodsi3.c10
-rw-r--r--arch/parisc/lib/libgcc/__umulsidi3.c46
-rw-r--r--arch/parisc/lib/libgcc/libgcc.h32
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 @@
1obj-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
3u64 __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}
19EXPORT_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
3u64 __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}
19EXPORT_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
3u32 __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}
30EXPORT_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
3s64 __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}
23EXPORT_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
3s32 __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}
23EXPORT_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
3u64 __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}
19EXPORT_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
3s64 __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}
23EXPORT_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
3s32 __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}
23EXPORT_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
3union DWunion {
4 struct {
5 s32 high;
6 s32 low;
7 } s;
8 s64 ll;
9};
10
11s64 __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}
22EXPORT_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
3u64 __udivdi3(u64 num, u64 den)
4{
5 return __udivmoddi4(num, den, NULL);
6}
7EXPORT_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
3u64 __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}
31EXPORT_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
3u32 __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}
31EXPORT_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
3u32 __udivsi3(u32 num, u32 den)
4{
5 return __udivmodsi4(num, den, NULL);
6}
7EXPORT_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
3u64 __umoddi3(u64 num, u64 den)
4{
5 u64 v;
6
7 (void)__udivmoddi4(num, den, &v);
8 return v;
9}
10EXPORT_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
3u32 __umodsi3(u32 num, u32 den)
4{
5 u32 v;
6
7 (void)__udivmodsi4(num, den, &v);
8 return v;
9}
10EXPORT_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
31union DWunion {
32 struct {
33 s32 high;
34 s32 low;
35 } s;
36 s64 ll;
37};
38
39u64 __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/ */
8u64 __ashldi3(u64 v, int cnt);
9u64 __ashrdi3(u64 v, int cnt);
10
11u32 __clzsi2(u32 v);
12
13s64 __divdi3(s64 num, s64 den);
14s32 __divsi3(s32 num, s32 den);
15
16u64 __lshrdi3(u64 v, int cnt);
17
18s64 __moddi3(s64 num, s64 den);
19s32 __modsi3(s32 num, s32 den);
20
21u64 __udivdi3(u64 num, u64 den);
22u32 __udivsi3(u32 num, u32 den);
23
24u64 __udivmoddi4(u64 num, u64 den, u64 * rem_p);
25u32 __udivmodsi4(u32 num, u32 den, u32 * rem_p);
26
27u64 __umulsidi3(u32 u, u32 v);
28
29u64 __umoddi3(u64 num, u64 den);
30u32 __umodsi3(u32 num, u32 den);
31
32#endif /*_PA_LIBGCC_H_*/