[PARISC] import necessary bits of libgcc.a

Currently we're hacking libs-y to include libgcc.a, but this has
unforeseen consequences since the userspace libgcc is linked with fpregs
enabled. We need the kernel to stop using fpregs in an uncontrolled manner
to implement lazy fpu state saves.

Signed-off-by: Kyle McMartin <kyle@mcmartin.ca>
This commit is contained in:
Kyle McMartin
2007-10-18 00:06:26 -07:00
committed by Kyle McMartin
parent 6f7d998e94
commit efb80e7e09
31 changed files with 4628 additions and 24 deletions
+1 -1
View File
@@ -4,4 +4,4 @@
lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o
obj-y := iomap.o
obj-y := libgcc/ milli/ iomap.o
+4
View File
@@ -0,0 +1,4 @@
obj-y := __ashldi3.o __ashrdi3.o __clzsi2.o __divdi3.o __divsi3.o \
__lshrdi3.o __moddi3.o __modsi3.o __udivdi3.o \
__udivmoddi4.o __udivmodsi4.o __udivsi3.o \
__umoddi3.o __umodsi3.o __muldi3.o __umulsidi3.o
+19
View File
@@ -0,0 +1,19 @@
#include "libgcc.h"
u64 __ashldi3(u64 v, int cnt)
{
int c = cnt & 31;
u32 vl = (u32) v;
u32 vh = (u32) (v >> 32);
if (cnt & 32) {
vh = (vl << c);
vl = 0;
} else {
vh = (vh << c) + (vl >> (32 - c));
vl = (vl << c);
}
return ((u64) vh << 32) + vl;
}
EXPORT_SYMBOL(__ashldi3);
+19
View File
@@ -0,0 +1,19 @@
#include "libgcc.h"
u64 __ashrdi3(u64 v, int cnt)
{
int c = cnt & 31;
u32 vl = (u32) v;
u32 vh = (u32) (v >> 32);
if (cnt & 32) {
vl = ((s32) vh >> c);
vh = (s32) vh >> 31;
} else {
vl = (vl >> c) + (vh << (32 - c));
vh = ((s32) vh >> c);
}
return ((u64) vh << 32) + vl;
}
EXPORT_SYMBOL(__ashrdi3);
+30
View File
@@ -0,0 +1,30 @@
#include "libgcc.h"
u32 __clzsi2(u32 v)
{
int p = 31;
if (v & 0xffff0000) {
p -= 16;
v >>= 16;
}
if (v & 0xff00) {
p -= 8;
v >>= 8;
}
if (v & 0xf0) {
p -= 4;
v >>= 4;
}
if (v & 0xc) {
p -= 2;
v >>= 2;
}
if (v & 0x2) {
p -= 1;
v >>= 1;
}
return p;
}
EXPORT_SYMBOL(__clzsi2);
+23
View File
@@ -0,0 +1,23 @@
#include "libgcc.h"
s64 __divdi3(s64 num, s64 den)
{
int minus = 0;
s64 v;
if (num < 0) {
num = -num;
minus = 1;
}
if (den < 0) {
den = -den;
minus ^= 1;
}
v = __udivmoddi4(num, den, NULL);
if (minus)
v = -v;
return v;
}
EXPORT_SYMBOL(__divdi3);
+23
View File
@@ -0,0 +1,23 @@
#include "libgcc.h"
s32 __divsi3(s32 num, s32 den)
{
int minus = 0;
s32 v;
if (num < 0) {
num = -num;
minus = 1;
}
if (den < 0) {
den = -den;
minus ^= 1;
}
v = __udivmodsi4(num, den, NULL);
if (minus)
v = -v;
return v;
}
EXPORT_SYMBOL(__divsi3);
+19
View File
@@ -0,0 +1,19 @@
#include "libgcc.h"
u64 __lshrdi3(u64 v, int cnt)
{
int c = cnt & 31;
u32 vl = (u32) v;
u32 vh = (u32) (v >> 32);
if (cnt & 32) {
vl = (vh >> c);
vh = 0;
} else {
vl = (vl >> c) + (vh << (32 - c));
vh = (vh >> c);
}
return ((u64) vh << 32) + vl;
}
EXPORT_SYMBOL(__lshrdi3);
+23
View File
@@ -0,0 +1,23 @@
#include "libgcc.h"
s64 __moddi3(s64 num, s64 den)
{
int minus = 0;
s64 v;
if (num < 0) {
num = -num;
minus = 1;
}
if (den < 0) {
den = -den;
minus ^= 1;
}
(void)__udivmoddi4(num, den, (u64 *) & v);
if (minus)
v = -v;
return v;
}
EXPORT_SYMBOL(__moddi3);
+23
View File
@@ -0,0 +1,23 @@
#include "libgcc.h"
s32 __modsi3(s32 num, s32 den)
{
int minus = 0;
s32 v;
if (num < 0) {
num = -num;
minus = 1;
}
if (den < 0) {
den = -den;
minus ^= 1;
}
(void)__udivmodsi4(num, den, (u32 *) & v);
if (minus)
v = -v;
return v;
}
EXPORT_SYMBOL(__modsi3);
+22
View File
@@ -0,0 +1,22 @@
#include "libgcc.h"
union DWunion {
struct {
s32 high;
s32 low;
} s;
s64 ll;
};
s64 __muldi3(s64 u, s64 v)
{
const union DWunion uu = { .ll = u };
const union DWunion vv = { .ll = v };
union DWunion w = { .ll = __umulsidi3(uu.s.low, vv.s.low) };
w.s.high += ((u32)uu.s.low * (u32)vv.s.high
+ (u32)uu.s.high * (u32)vv.s.low);
return w.ll;
}
EXPORT_SYMBOL(__muldi3);
+7
View File
@@ -0,0 +1,7 @@
#include "libgcc.h"
u64 __udivdi3(u64 num, u64 den)
{
return __udivmoddi4(num, den, NULL);
}
EXPORT_SYMBOL(__udivdi3);
+31
View File
@@ -0,0 +1,31 @@
#include "libgcc.h"
u64 __udivmoddi4(u64 num, u64 den, u64 * rem_p)
{
u64 quot = 0, qbit = 1;
if (den == 0) {
BUG();
}
/* Left-justify denominator and count shift */
while ((s64) den >= 0) {
den <<= 1;
qbit <<= 1;
}
while (qbit) {
if (den <= num) {
num -= den;
quot += qbit;
}
den >>= 1;
qbit >>= 1;
}
if (rem_p)
*rem_p = num;
return quot;
}
EXPORT_SYMBOL(__udivmoddi4);
+31
View File
@@ -0,0 +1,31 @@
#include "libgcc.h"
u32 __udivmodsi4(u32 num, u32 den, u32 * rem_p)
{
u32 quot = 0, qbit = 1;
if (den == 0) {
BUG();
}
/* Left-justify denominator and count shift */
while ((s32) den >= 0) {
den <<= 1;
qbit <<= 1;
}
while (qbit) {
if (den <= num) {
num -= den;
quot += qbit;
}
den >>= 1;
qbit >>= 1;
}
if (rem_p)
*rem_p = num;
return quot;
}
EXPORT_SYMBOL(__udivmodsi4);
+7
View File
@@ -0,0 +1,7 @@
#include "libgcc.h"
u32 __udivsi3(u32 num, u32 den)
{
return __udivmodsi4(num, den, NULL);
}
EXPORT_SYMBOL(__udivsi3);
+10
View File
@@ -0,0 +1,10 @@
#include "libgcc.h"
u64 __umoddi3(u64 num, u64 den)
{
u64 v;
(void)__udivmoddi4(num, den, &v);
return v;
}
EXPORT_SYMBOL(__umoddi3);
+10
View File
@@ -0,0 +1,10 @@
#include "libgcc.h"
u32 __umodsi3(u32 num, u32 den)
{
u32 v;
(void)__udivmodsi4(num, den, &v);
return v;
}
EXPORT_SYMBOL(__umodsi3);
+46
View File
@@ -0,0 +1,46 @@
#include "libgcc.h"
#define __ll_B ((u32) 1 << (32 / 2))
#define __ll_lowpart(t) ((u32) (t) & (__ll_B - 1))
#define __ll_highpart(t) ((u32) (t) >> 16)
#define umul_ppmm(w1, w0, u, v) \
do { \
u32 __x0, __x1, __x2, __x3; \
u16 __ul, __vl, __uh, __vh; \
\
__ul = __ll_lowpart (u); \
__uh = __ll_highpart (u); \
__vl = __ll_lowpart (v); \
__vh = __ll_highpart (v); \
\
__x0 = (u32) __ul * __vl; \
__x1 = (u32) __ul * __vh; \
__x2 = (u32) __uh * __vl; \
__x3 = (u32) __uh * __vh; \
\
__x1 += __ll_highpart (__x0);/* this can't give carry */ \
__x1 += __x2; /* but this indeed can */ \
if (__x1 < __x2) /* did we get it? */ \
__x3 += __ll_B; /* yes, add it in the proper pos. */ \
\
(w1) = __x3 + __ll_highpart (__x1); \
(w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
} while (0)
union DWunion {
struct {
s32 high;
s32 low;
} s;
s64 ll;
};
u64 __umulsidi3(u32 u, u32 v)
{
union DWunion __w;
umul_ppmm(__w.s.high, __w.s.low, u, v);
return __w.ll;
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef _PA_LIBGCC_H_
#define _PA_LIBGCC_H_
#include <linux/types.h>
#include <linux/module.h>
/* Cribbed from klibc/libgcc/ */
u64 __ashldi3(u64 v, int cnt);
u64 __ashrdi3(u64 v, int cnt);
u32 __clzsi2(u32 v);
s64 __divdi3(s64 num, s64 den);
s32 __divsi3(s32 num, s32 den);
u64 __lshrdi3(u64 v, int cnt);
s64 __moddi3(s64 num, s64 den);
s32 __modsi3(s32 num, s32 den);
u64 __udivdi3(u64 num, u64 den);
u32 __udivsi3(u32 num, u32 den);
u64 __udivmoddi4(u64 num, u64 den, u64 * rem_p);
u32 __udivmodsi4(u32 num, u32 den, u32 * rem_p);
u64 __umulsidi3(u32 u, u32 v);
u64 __umoddi3(u64 num, u64 den);
u32 __umodsi3(u32 num, u32 den);
#endif /*_PA_LIBGCC_H_*/
+1
View File
@@ -0,0 +1 @@
obj-y := dyncall.o divI.o divU.o remI.o remU.o div_const.o mulI.o

Some files were not shown because too many files have changed in this diff Show More