Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 803 → Rev 804

/uspace/trunk/softfloat/include/sftypes.h
37,9 → 37,9
#ifdef __BIG_ENDIAN__
__u32 sign:1;
__u32 exp:8;
__u32 mantisa:23;
__u32 fraction:23;
#elif defined __LITTLE_ENDIAN__
__u32 mantisa:23;
__u32 fraction:23;
__u32 exp:8;
__u32 sign:1;
#else
56,9 → 56,9
#ifdef __BIG_ENDIAN__
__u64 sign:1;
__u64 exp:11;
__u64 mantisa:52;
__u64 fraction:52;
#elif defined __LITTLE_ENDIAN__
__u64 mantisa:52;
__u64 fraction:52;
__u64 exp:11;
__u64 sign:1;
#else
81,8 → 81,8
#define FLOAT64_SIGNAN 0x7FF0000000000001ll
#define FLOAT64_INF 0x7FF0000000000000ll
 
#define FLOAT32_MANTISA_SIZE 23
#define FLOAT64_MANTISA_SIZE 52
#define FLOAT32_FRACTION_SIZE 23
#define FLOAT64_FRACTION_SIZE 52
 
#define FLOAT32_HIDDEN_BIT_MASK 0x800000
#define FLOAT64_HIDDEN_BIT_MASK 0x10000000000000ll
/uspace/trunk/softfloat/generic/softfloat.c
43,45 → 43,45
float __addsf3(float a, float b)
{
float32 fa, fb;
fa.f=a;
fb.f=b;
if (fa.parts.sign!=fb.parts.sign) {
fa.f = a;
fb.f = b;
if (fa.parts.sign != fb.parts.sign) {
if (fa.parts.sign) {
fa.parts.sign=0;
return subFloat32(fb,fa).f;
fa.parts.sign = 0;
return subFloat32(fb, fa).f;
};
fb.parts.sign=0;
return subFloat32(fa,fb).f;
fb.parts.sign = 0;
return subFloat32(fa, fb).f;
}
return addFloat32(fa,fb).f;
return addFloat32(fa, fb).f;
}
 
double __adddf3(double a, double b)
{
float64 da, db;
da.d=a;
db.d=b;
if (da.parts.sign!=db.parts.sign) {
da.d = a;
db.d = b;
if (da.parts.sign != db.parts.sign) {
if (da.parts.sign) {
da.parts.sign=0;
return subFloat64(db,da).d;
da.parts.sign = 0;
return subFloat64(db, da).d;
};
db.parts.sign=0;
return subFloat64(da,db).d;
db.parts.sign = 0;
return subFloat64(da, db).d;
}
return addFloat64(da,db).d;
return addFloat64(da, db).d;
}
 
float __subsf3(float a, float b)
{
float32 fa, fb;
fa.f=a;
fb.f=b;
if (fa.parts.sign!=fb.parts.sign) {
fb.parts.sign=!fb.parts.sign;
return addFloat32(fa,fb).f;
fa.f = a;
fb.f = b;
if (fa.parts.sign != fb.parts.sign) {
fb.parts.sign = !fb.parts.sign;
return addFloat32(fa, fb).f;
}
return subFloat32(fa,fb).f;
return subFloat32(fa, fb).f;
}
 
double __subdf3(double a, double b)
99,8 → 99,8
float __mulsf3(float a, float b)
{
float32 fa, fb;
fa.f=a;
fb.f=b;
fa.f = a;
fb.f = b;
return mulFloat32(fa, fb).f;
}
 
115,16 → 115,16
float __divsf3(float a, float b)
{
float32 fa, fb;
fa.f=a;
fb.f=b;
//return divFloat32(fa, fb).f;
fa.f = a;
fb.f = b;
return divFloat32(fa, fb).f;
}
 
float __negsf2(float a)
{
float32 fa;
fa.f=a;
fa.parts.sign=!fa.parts.sign;
fa.f = a;
fa.parts.sign = !fa.parts.sign;
return fa.f;
}
 
131,8 → 131,8
double __negdf2(double a)
{
float64 fa;
fa.d=a;
fa.parts.sign=!fa.parts.sign;
fa.d = a;
fa.parts.sign = !fa.parts.sign;
return fa.d;
}
 
161,19 → 161,19
 
int __cmpsf2(float a, float b)
{
float32 fa,fb;
fa.f=a;
fb.f=b;
if ((isFloat32NaN(fa))||(isFloat32NaN(fb))) {
float32 fa, fb;
fa.f = a;
fb.f = b;
if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
return 1; /* no special constant for unordered - maybe signaled? */
};
 
if (isFloat32eq(fa,fb)) {
if (isFloat32eq(fa, fb)) {
return 0;
};
if (isFloat32lt(fa,fb)) {
if (isFloat32lt(fa, fb)) {
return -1;
};
return 1;
181,10 → 181,10
 
int __unordsf2(float a, float b)
{
float32 fa,fb;
fa.f=a;
fb.f=b;
return ((isFloat32NaN(fa))||(isFloat32NaN(fb)));
float32 fa, fb;
fa.f = a;
fb.f = b;
return ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) );
}
 
/**
192,38 → 192,38
* */
int __eqsf2(float a, float b)
{
float32 fa,fb;
fa.f=a;
fb.f=b;
if ((isFloat32NaN(fa))||(isFloat32NaN(fb))) {
float32 fa, fb;
fa.f = a;
fb.f = b;
if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
/* TODO: sigNaNs*/
return 1;
};
return isFloat32eq(fa,fb)-1;
return isFloat32eq(fa, fb) - 1;
}
 
/* strange behavior, but it was in gcc documentation */
int __nesf2(float a, float b)
{
return __eqsf2(a,b);
return __eqsf2(a, b);
}
 
/* return value >= 0 if a>=b and neither is NaN */
int __gesf2(float a, float b)
{
float32 fa,fb;
fa.f=a;
fb.f=b;
if ((isFloat32NaN(fa))||(isFloat32NaN(fb))) {
float32 fa, fb;
fa.f = a;
fb.f = b;
if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
/* TODO: sigNaNs*/
return -1;
};
if (isFloat32eq(fa,fb)) {
if (isFloat32eq(fa, fb)) {
return 0;
};
if (isFloat32gt(fa,fb)) {
if (isFloat32gt(fa, fb)) {
return 1;
};
233,10 → 233,10
/** Return negative value, if a<b and neither is NaN*/
int __ltsf2(float a, float b)
{
float32 fa,fb;
fa.f=a;
fb.f=b;
if ((isFloat32NaN(fa))||(isFloat32NaN(fb))) {
float32 fa, fb;
fa.f = a;
fb.f = b;
if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
/* TODO: sigNaNs*/
return 1;
};
249,19 → 249,19
/* return value <= 0 if a<=b and neither is NaN */
int __lesf2(float a, float b)
{
float32 fa,fb;
fa.f=a;
fb.f=b;
if ((isFloat32NaN(fa))||(isFloat32NaN(fb))) {
float32 fa, fb;
fa.f = a;
fb.f = b;
if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
/* TODO: sigNaNs*/
return 1;
};
if (isFloat32eq(fa,fb)) {
if (isFloat32eq(fa, fb)) {
return 0;
};
if (isFloat32lt(fa,fb)) {
if (isFloat32lt(fa, fb)) {
return -1;
};
271,10 → 271,10
/** Return positive value, if a>b and neither is NaN*/
int __gtsf2(float a, float b)
{
float32 fa,fb;
fa.f=a;
fb.f=b;
if ((isFloat32NaN(fa))||(isFloat32NaN(fb))) {
float32 fa, fb;
fa.f = a;
fb.f = b;
if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
/* TODO: sigNaNs*/
return -1;
};
288,16 → 288,16
 
float __powisf2(float a, int b)
{
//TODO:
/* TODO: */
}
 
float __mulsc3(float a, float b, float c, float d)
{
//TODO:
/* TODO: */
}
 
float __divsc3(float a, float b, float c, float d)
{
//TODO:
/* TODO: */
}
 
/uspace/trunk/softfloat/generic/div.c
32,7 → 32,156
 
float32 divFloat32(float32 a, float32 b)
{
/* TODO: */
float32 result;
__s32 aexp, bexp, cexp;
__u64 afrac, bfrac, cfrac;
result.parts.sign = a.parts.sign ^ b.parts.sign;
if (isFloat32NaN(a)) {
if (isFloat32SigNaN(a)) {
/*FIXME: SigNaN*/
}
/*NaN*/
return a;
}
if (isFloat32NaN(b)) {
if (isFloat32SigNaN(b)) {
/*FIXME: SigNaN*/
}
/*NaN*/
return b;
}
if (isFloat32Infinity(a)) {
if (isFloat32Infinity(b)) {
/*FIXME: inf / inf */
result.binary = FLOAT32_NAN;
return result;
}
/* inf / num */
result.parts.exp = a.parts.exp;
result.parts.fraction = a.parts.fraction;
return result;
}
 
if (isFloat32Infinity(b)) {
if (isFloat32Zero(a)) {
/* FIXME 0 / inf */
result.parts.exp = 0;
result.parts.fraction = 0;
return result;
}
/* FIXME: num / inf*/
result.parts.exp = 0;
result.parts.fraction = 0;
return result;
}
if (isFloat32Zero(b)) {
if (isFloat32Zero(a)) {
/*FIXME: 0 / 0*/
result.binary = FLOAT32_NAN;
return result;
}
/* FIXME: division by zero */
result.parts.exp = 0;
result.parts.fraction = 0;
return result;
}
 
afrac = a.parts.fraction;
aexp = a.parts.exp;
bfrac = b.parts.fraction;
bexp = b.parts.exp;
/* denormalized numbers */
if (aexp == 0) {
if (afrac == 0) {
result.parts.exp = 0;
result.parts.fraction = 0;
return result;
}
/* normalize it*/
afrac <<= 1;
/* afrac is nonzero => it must stop */
while (! (afrac & FLOAT32_HIDDEN_BIT_MASK) ) {
afrac <<= 1;
aexp--;
}
}
 
if (bexp == 0) {
bfrac <<= 1;
/* bfrac is nonzero => it must stop */
while (! (bfrac & FLOAT32_HIDDEN_BIT_MASK) ) {
bfrac <<= 1;
bexp--;
}
}
 
afrac = (afrac | FLOAT32_HIDDEN_BIT_MASK ) << (32 - FLOAT32_FRACTION_SIZE - 1 );
bfrac = (bfrac | FLOAT32_HIDDEN_BIT_MASK ) << (32 - FLOAT32_FRACTION_SIZE );
 
if ( bfrac <= (afrac << 1) ) {
afrac >>= 1;
aexp++;
}
cexp = aexp - bexp + FLOAT32_BIAS - 2;
cfrac = (afrac << 32) / bfrac;
if (( cfrac & 0x3F ) == 0) {
cfrac |= ( bfrac * cfrac != afrac << 32 );
}
/* pack and round */
/* TODO: find first nonzero digit and shift result and detect possibly underflow */
while ((cexp > 0) && (cfrac) && (!(cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7 )))) {
cexp--;
cfrac <<= 1;
/* TODO: fix underflow */
};
cfrac += (0x1 << 6); /* FIXME: 7 is not sure*/
if (cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
++cexp;
cfrac >>= 1;
}
 
/* check overflow */
if (cexp >= FLOAT32_MAX_EXPONENT ) {
/* FIXME: overflow, return infinity */
result.parts.exp = FLOAT32_MAX_EXPONENT;
result.parts.fraction = 0;
return result;
}
 
if (cexp < 0) {
/* FIXME: underflow */
result.parts.exp = 0;
if ((cexp + FLOAT32_FRACTION_SIZE) < 0) {
result.parts.fraction = 0;
return result;
}
cfrac >>= 1;
while (cexp < 0) {
cexp ++;
cfrac >>= 1;
}
} else {
result.parts.exp = (__u32)cexp;
}
result.parts.fraction = ((cfrac >> 6) & (~FLOAT32_HIDDEN_BIT_MASK));
return result;
}
 
/uspace/trunk/softfloat/generic/conversion.c
32,11 → 32,11
float64 convertFloat32ToFloat64(float32 a)
{
float64 result;
__u64 mant;
__u64 frac;
result.parts.sign = a.parts.sign;
result.parts.mantisa = a.parts.mantisa;
result.parts.mantisa <<= (FLOAT64_MANTISA_SIZE - FLOAT32_MANTISA_SIZE );
result.parts.fraction = a.parts.fraction;
result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE );
if ((isFloat32Infinity(a))||(isFloat32NaN(a))) {
result.parts.exp = 0x7FF;
48,20 → 48,20
if (a.parts.exp == 0) {
/* normalize denormalized numbers */
 
if (result.parts.mantisa == 0ll) { /* fix zero */
if (result.parts.fraction == 0ll) { /* fix zero */
result.parts.exp = 0ll;
return result;
}
mant = result.parts.mantisa;
frac = result.parts.fraction;
while (!(mant & (0x10000000000000ll))) {
mant <<= 1;
while (!(frac & (0x10000000000000ll))) {
frac <<= 1;
--result.parts.exp;
};
++result.parts.exp;
result.parts.mantisa = mant;
result.parts.fraction = frac;
};
return result;
72,7 → 72,7
{
float32 result;
__s32 exp;
__u64 mant;
__u64 frac;
result.parts.sign = a.parts.sign;
81,16 → 81,16
result.parts.exp = 0xFF;
if (isFloat64SigNaN(a)) {
result.parts.mantisa = 0x800000; /* set first bit of mantisa nonzero */
result.parts.fraction = 0x800000; /* set first bit of fraction nonzero */
return result;
}
result.parts.mantisa = 0x1; /* mantisa nonzero but its first bit is zero */
result.parts.fraction = 0x1; /* fraction nonzero but its first bit is zero */
return result;
};
 
if (isFloat64Infinity(a)) {
result.parts.mantisa = 0;
result.parts.fraction = 0;
result.parts.exp = 0xFF;
return result;
};
99,7 → 99,7
if (exp >= 0xFF) {
/*FIXME: overflow*/
result.parts.mantisa = 0;
result.parts.fraction = 0;
result.parts.exp = 0xFF;
return result;
110,30 → 110,30
result.parts.exp = 0;
exp *= -1;
if (exp > FLOAT32_MANTISA_SIZE ) {
if (exp > FLOAT32_FRACTION_SIZE ) {
/* FIXME: underflow */
result.parts.mantisa = 0;
result.parts.fraction = 0;
return result;
};
/* denormalized */
mant = a.parts.mantisa;
mant |= 0x10000000000000ll; /* denormalize and set hidden bit */
frac = a.parts.fraction;
frac |= 0x10000000000000ll; /* denormalize and set hidden bit */
mant >>= (FLOAT64_MANTISA_SIZE - FLOAT32_MANTISA_SIZE + 1);
frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
while (exp > 0) {
--exp;
mant >>= 1;
frac >>= 1;
};
result.parts.mantisa = mant;
result.parts.fraction = frac;
return result;
};
 
result.parts.exp = exp;
result.parts.mantisa = a.parts.mantisa >> (FLOAT64_MANTISA_SIZE - FLOAT32_MANTISA_SIZE);
result.parts.fraction = a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
return result;
};
 
/uspace/trunk/softfloat/generic/add.c
35,12 → 35,12
float32 addFloat32(float32 a, float32 b)
{
int expdiff;
__u32 exp1, exp2,mant1, mant2;
__u32 exp1, exp2,frac1, frac2;
expdiff = a.parts.exp - b.parts.exp;
if (expdiff < 0) {
if (isFloat32NaN(b)) {
//TODO: fix SigNaN
/* TODO: fix SigNaN */
if (isFloat32SigNaN(b)) {
};
 
51,17 → 51,17
return b;
}
mant1 = b.parts.mantisa;
frac1 = b.parts.fraction;
exp1 = b.parts.exp;
mant2 = a.parts.mantisa;
frac2 = a.parts.fraction;
exp2 = a.parts.exp;
expdiff *= -1;
} else {
if (isFloat32NaN(a)) {
//TODO: fix SigNaN
if ((isFloat32NaN(a)) || (isFloat32NaN(b))) {
/* TODO: fix SigNaN */
if (isFloat32SigNaN(a) || isFloat32SigNaN(b)) {
};
return a;
return (isFloat32NaN(a)?a:b);
};
if (a.parts.exp == FLOAT32_MAX_EXPONENT) {
68,24 → 68,24
return a;
}
mant1 = a.parts.mantisa;
frac1 = a.parts.fraction;
exp1 = a.parts.exp;
mant2 = b.parts.mantisa;
frac2 = b.parts.fraction;
exp2 = b.parts.exp;
};
if (exp1 == 0) {
/* both are denormalized */
mant1 += mant2;
if (mant1 & FLOAT32_HIDDEN_BIT_MASK ) {
frac1 += frac2;
if (frac1 & FLOAT32_HIDDEN_BIT_MASK ) {
/* result is not denormalized */
a.parts.exp = 1;
};
a.parts.mantisa = mant1;
a.parts.fraction = frac1;
return a;
};
mant1 |= FLOAT32_HIDDEN_BIT_MASK; //add hidden bit
frac1 |= FLOAT32_HIDDEN_BIT_MASK; /* add hidden bit */
 
if (exp2 == 0) {
/* second operand is denormalized */
92,37 → 92,43
--expdiff;
} else {
/* add hidden bit to second operand */
mant2 |= FLOAT32_HIDDEN_BIT_MASK;
frac2 |= FLOAT32_HIDDEN_BIT_MASK;
};
/* create some space for rounding */
mant1 <<= 6;
mant2 <<= 6;
frac1 <<= 6;
frac2 <<= 6;
if (expdiff > (FLOAT32_MANTISA_SIZE + 1) ) {
goto done;
};
if (expdiff < (FLOAT32_FRACTION_SIZE + 2) ) {
frac2 >>= expdiff;
frac1 += frac2;
};
mant2 >>= expdiff;
mant1 += mant2;
done:
if (mant1 & (FLOAT32_HIDDEN_BIT_MASK << 7) ) {
if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7) ) {
++exp1;
mant1 >>= 1;
frac1 >>= 1;
};
/* rounding - if first bit after mantisa is set then round up */
mant1 += (0x1 << 5);
/* rounding - if first bit after fraction is set then round up */
frac1 += (0x1 << 5);
if (mant1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
/* rounding overflow */
++exp1;
mant1 >>= 1;
frac1 >>= 1;
};
if ((a.parts.exp == FLOAT32_MAX_EXPONENT ) || (a.parts.exp < exp1)) {
/* overflow - set infinity as result */
a.parts.exp = FLOAT32_MAX_EXPONENT;
a.parts.fraction = 0;
return a;
}
a.parts.exp = exp1;
/*Clear hidden bit and shift */
a.parts.mantisa = ((mant1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)) ;
a.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)) ;
return a;
}
 
133,12 → 139,12
{
int expdiff;
__u32 exp1, exp2;
__u64 mant1, mant2;
__u64 frac1, frac2;
expdiff = a.parts.exp - b.parts.exp;
if (expdiff < 0) {
if (isFloat64NaN(b)) {
//TODO: fix SigNaN
/* TODO: fix SigNaN */
if (isFloat64SigNaN(b)) {
};
 
150,14 → 156,14
return b;
}
mant1 = b.parts.mantisa;
frac1 = b.parts.fraction;
exp1 = b.parts.exp;
mant2 = a.parts.mantisa;
frac2 = a.parts.fraction;
exp2 = a.parts.exp;
expdiff *= -1;
} else {
if (isFloat64NaN(a)) {
//TODO: fix SigNaN
/* TODO: fix SigNaN */
if (isFloat64SigNaN(a) || isFloat64SigNaN(b)) {
};
return a;
168,25 → 174,25
return a;
}
mant1 = a.parts.mantisa;
frac1 = a.parts.fraction;
exp1 = a.parts.exp;
mant2 = b.parts.mantisa;
frac2 = b.parts.fraction;
exp2 = b.parts.exp;
};
if (exp1 == 0) {
/* both are denormalized */
mant1 += mant2;
if (mant1 & FLOAT64_HIDDEN_BIT_MASK) {
frac1 += frac2;
if (frac1 & FLOAT64_HIDDEN_BIT_MASK) {
/* result is not denormalized */
a.parts.exp = 1;
};
a.parts.mantisa = mant1;
a.parts.fraction = frac1;
return a;
};
/* add hidden bit - mant1 is sure not denormalized */
mant1 |= FLOAT64_HIDDEN_BIT_MASK;
/* add hidden bit - frac1 is sure not denormalized */
frac1 |= FLOAT64_HIDDEN_BIT_MASK;
 
/* second operand ... */
if (exp2 == 0) {
194,36 → 200,42
--expdiff;
} else {
/* is not denormalized */
mant2 |= FLOAT64_HIDDEN_BIT_MASK;
frac2 |= FLOAT64_HIDDEN_BIT_MASK;
};
/* create some space for rounding */
mant1 <<= 6;
mant2 <<= 6;
frac1 <<= 6;
frac2 <<= 6;
if (expdiff > (FLOAT64_MANTISA_SIZE + 1) ) {
goto done;
};
if (expdiff < (FLOAT64_FRACTION_SIZE + 2) ) {
frac2 >>= expdiff;
frac1 += frac2;
};
mant2 >>= expdiff;
mant1 += mant2;
done:
if (mant1 & (FLOAT64_HIDDEN_BIT_MASK << 7) ) {
if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7) ) {
++exp1;
mant1 >>= 1;
frac1 >>= 1;
};
/* rounding - if first bit after mantisa is set then round up */
mant1 += (0x1 << 5);
/* rounding - if first bit after fraction is set then round up */
frac1 += (0x1 << 5);
if (mant1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
/* rounding overflow */
++exp1;
mant1 >>= 1;
frac1 >>= 1;
};
if ((a.parts.exp == FLOAT64_MAX_EXPONENT ) || (a.parts.exp < exp1)) {
/* overflow - set infinity as result */
a.parts.exp = FLOAT64_MAX_EXPONENT;
a.parts.fraction = 0;
return a;
}
a.parts.exp = exp1;
/*Clear hidden bit and shift */
a.parts.mantisa = ( (mant1 >> 6 ) & (~FLOAT64_HIDDEN_BIT_MASK));
a.parts.fraction = ( (frac1 >> 6 ) & (~FLOAT64_HIDDEN_BIT_MASK));
return a;
}
 
/uspace/trunk/softfloat/generic/sub.c
35,15 → 35,15
float32 subFloat32(float32 a, float32 b)
{
int expdiff;
__u32 exp1, exp2, mant1, mant2;
__u32 exp1, exp2, frac1, frac2;
float32 result;
 
result.f = 0;
expdiff = a.parts.exp - b.parts.exp;
if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.mantisa < b.parts.mantisa))) {
if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.fraction < b.parts.fraction))) {
if (isFloat32NaN(b)) {
//TODO: fix SigNaN
/* TODO: fix SigNaN */
if (isFloat32SigNaN(b)) {
};
return b;
56,14 → 56,14
result.parts.sign = !a.parts.sign;
mant1 = b.parts.mantisa;
frac1 = b.parts.fraction;
exp1 = b.parts.exp;
mant2 = a.parts.mantisa;
frac2 = a.parts.fraction;
exp2 = a.parts.exp;
expdiff *= -1;
} else {
if (isFloat32NaN(a)) {
//TODO: fix SigNaN
/* TODO: fix SigNaN */
if (isFloat32SigNaN(a) || isFloat32SigNaN(b)) {
};
return a;
72,7 → 72,7
if (a.parts.exp == FLOAT32_MAX_EXPONENT) {
if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
/* inf - inf => nan */
//TODO: fix exception
/* TODO: fix exception */
result.binary = FLOAT32_NAN;
return result;
};
81,17 → 81,17
result.parts.sign = a.parts.sign;
mant1 = a.parts.mantisa;
frac1 = a.parts.fraction;
exp1 = a.parts.exp;
mant2 = b.parts.mantisa;
frac2 = b.parts.fraction;
exp2 = b.parts.exp;
};
if (exp1 == 0) {
//both are denormalized
result.parts.mantisa = mant1-mant2;
if (result.parts.mantisa > mant1) {
//TODO: underflow exception
/* both are denormalized */
result.parts.fraction = frac1-frac2;
if (result.parts.fraction > frac1) {
/* TODO: underflow exception */
return result;
};
result.parts.exp = 0;
99,7 → 99,7
};
 
/* add hidden bit */
mant1 |= FLOAT32_HIDDEN_BIT_MASK;
frac1 |= FLOAT32_HIDDEN_BIT_MASK;
if (exp2 == 0) {
/* denormalized */
106,36 → 106,36
--expdiff;
} else {
/* normalized */
mant2 |= FLOAT32_HIDDEN_BIT_MASK;
frac2 |= FLOAT32_HIDDEN_BIT_MASK;
};
/* create some space for rounding */
mant1 <<= 6;
mant2 <<= 6;
frac1 <<= 6;
frac2 <<= 6;
if (expdiff > FLOAT32_MANTISA_SIZE + 1) {
if (expdiff > FLOAT32_FRACTION_SIZE + 1) {
goto done;
};
mant1 = mant1 - (mant2 >> expdiff);
frac1 = frac1 - (frac2 >> expdiff);
done:
//TODO: find first nonzero digit and shift result and detect possibly underflow
while ((exp1 > 0) && (!(mant1 & (FLOAT32_HIDDEN_BIT_MASK << 6 )))) {
/* TODO: find first nonzero digit and shift result and detect possibly underflow */
while ((exp1 > 0) && (!(frac1 & (FLOAT32_HIDDEN_BIT_MASK << 6 )))) {
--exp1;
mant1 <<= 1;
/* TODO: fix underflow - mant1 == 0 does not necessary means underflow... */
frac1 <<= 1;
/* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */
};
/* rounding - if first bit after mantisa is set then round up */
mant1 += 0x20;
/* rounding - if first bit after fraction is set then round up */
frac1 += 0x20;
 
if (mant1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
++exp1;
mant1 >>= 1;
frac1 >>= 1;
};
/*Clear hidden bit and shift */
result.parts.mantisa = ((mant1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK));
result.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK));
result.parts.exp = exp1;
return result;
147,15 → 147,15
{
int expdiff;
__u32 exp1, exp2;
__u64 mant1, mant2;
__u64 frac1, frac2;
float64 result;
 
result.d = 0;
expdiff = a.parts.exp - b.parts.exp;
if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.mantisa < b.parts.mantisa))) {
if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.fraction < b.parts.fraction))) {
if (isFloat64NaN(b)) {
//TODO: fix SigNaN
/* TODO: fix SigNaN */
if (isFloat64SigNaN(b)) {
};
return b;
168,14 → 168,14
result.parts.sign = !a.parts.sign;
mant1 = b.parts.mantisa;
frac1 = b.parts.fraction;
exp1 = b.parts.exp;
mant2 = a.parts.mantisa;
frac2 = a.parts.fraction;
exp2 = a.parts.exp;
expdiff *= -1;
} else {
if (isFloat64NaN(a)) {
//TODO: fix SigNaN
/* TODO: fix SigNaN */
if (isFloat64SigNaN(a) || isFloat64SigNaN(b)) {
};
return a;
184,7 → 184,7
if (a.parts.exp == FLOAT64_MAX_EXPONENT) {
if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
/* inf - inf => nan */
//TODO: fix exception
/* TODO: fix exception */
result.binary = FLOAT64_NAN;
return result;
};
193,17 → 193,17
result.parts.sign = a.parts.sign;
mant1 = a.parts.mantisa;
frac1 = a.parts.fraction;
exp1 = a.parts.exp;
mant2 = b.parts.mantisa;
frac2 = b.parts.fraction;
exp2 = b.parts.exp;
};
if (exp1 == 0) {
//both are denormalized
result.parts.mantisa = mant1 - mant2;
if (result.parts.mantisa > mant1) {
//TODO: underflow exception
/* both are denormalized */
result.parts.fraction = frac1 - frac2;
if (result.parts.fraction > frac1) {
/* TODO: underflow exception */
return result;
};
result.parts.exp = 0;
211,7 → 211,7
};
 
/* add hidden bit */
mant1 |= FLOAT64_HIDDEN_BIT_MASK;
frac1 |= FLOAT64_HIDDEN_BIT_MASK;
if (exp2 == 0) {
/* denormalized */
218,36 → 218,36
--expdiff;
} else {
/* normalized */
mant2 |= FLOAT64_HIDDEN_BIT_MASK;
frac2 |= FLOAT64_HIDDEN_BIT_MASK;
};
/* create some space for rounding */
mant1 <<= 6;
mant2 <<= 6;
frac1 <<= 6;
frac2 <<= 6;
if (expdiff > FLOAT64_MANTISA_SIZE + 1) {
if (expdiff > FLOAT64_FRACTION_SIZE + 1) {
goto done;
};
mant1 = mant1 - (mant2 >> expdiff);
frac1 = frac1 - (frac2 >> expdiff);
done:
//TODO: find first nonzero digit and shift result and detect possibly underflow
while ((exp1 > 0) && (!(mant1 & (FLOAT64_HIDDEN_BIT_MASK << 6 )))) {
/* TODO: find first nonzero digit and shift result and detect possibly underflow */
while ((exp1 > 0) && (!(frac1 & (FLOAT64_HIDDEN_BIT_MASK << 6 )))) {
--exp1;
mant1 <<= 1;
/* TODO: fix underflow - mant1 == 0 does not necessary means underflow... */
frac1 <<= 1;
/* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */
};
/* rounding - if first bit after mantisa is set then round up */
mant1 += 0x20;
/* rounding - if first bit after fraction is set then round up */
frac1 += 0x20;
 
if (mant1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
++exp1;
mant1 >>= 1;
frac1 >>= 1;
};
/*Clear hidden bit and shift */
result.parts.mantisa = ((mant1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK));
result.parts.fraction = ((frac1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK));
result.parts.exp = exp1;
return result;
/uspace/trunk/softfloat/generic/comparison.c
30,33 → 30,33
#include<comparison.h>
 
inline int isFloat32NaN(float32 f)
{ /* NaN : exp = 0xff and nonzero mantisa */
return ((f.parts.exp==0xFF)&&(f.parts.mantisa));
{ /* NaN : exp = 0xff and nonzero fraction */
return ((f.parts.exp==0xFF)&&(f.parts.fraction));
};
 
inline int isFloat64NaN(float64 d)
{ /* NaN : exp = 0x7ff and nonzero mantisa */
return ((d.parts.exp==0x7FF)&&(d.parts.mantisa));
{ /* NaN : exp = 0x7ff and nonzero fraction */
return ((d.parts.exp==0x7FF)&&(d.parts.fraction));
};
 
inline int isFloat32SigNaN(float32 f)
{ /* SigNaN : exp = 0xff mantisa = 0xxxxx..x (binary), where at least one x is nonzero */
return ((f.parts.exp==0xFF)&&(f.parts.mantisa<0x400000)&&(f.parts.mantisa));
{ /* SigNaN : exp = 0xff fraction = 0xxxxx..x (binary), where at least one x is nonzero */
return ((f.parts.exp==0xFF)&&(f.parts.fraction<0x400000)&&(f.parts.fraction));
};
 
inline int isFloat64SigNaN(float64 d)
{ /* SigNaN : exp = 0x7ff mantisa = 0xxxxx..x (binary), where at least one x is nonzero */
return ((d.parts.exp==0x7FF)&&(d.parts.mantisa)&&(d.parts.mantisa<0x8000000000000ll));
{ /* SigNaN : exp = 0x7ff fraction = 0xxxxx..x (binary), where at least one x is nonzero */
return ((d.parts.exp==0x7FF)&&(d.parts.fraction)&&(d.parts.fraction<0x8000000000000ll));
};
 
inline int isFloat32Infinity(float32 f)
{
return ((f.parts.exp==0xFF)&&(f.parts.mantisa==0x0));
return ((f.parts.exp==0xFF)&&(f.parts.fraction==0x0));
};
 
inline int isFloat64Infinity(float64 d)
{
return ((d.parts.exp==0x7FF)&&(d.parts.mantisa==0x0));
return ((d.parts.exp==0x7FF)&&(d.parts.fraction==0x0));
};
 
inline int isFloat32Zero(float32 f)
/uspace/trunk/softfloat/generic/mul.c
36,7 → 36,7
float32 mulFloat32(float32 a, float32 b)
{
float32 result;
__u64 mant1, mant2;
__u64 frac1, frac2;
__s32 exp;
 
result.parts.sign = a.parts.sign ^ b.parts.sign;
44,12 → 44,12
if (isFloat32NaN(a) || isFloat32NaN(b) ) {
/* TODO: fix SigNaNs */
if (isFloat32SigNaN(a)) {
result.parts.mantisa = a.parts.mantisa;
result.parts.fraction = a.parts.fraction;
result.parts.exp = a.parts.exp;
return result;
};
if (isFloat32SigNaN(b)) { /* TODO: fix SigNaN */
result.parts.mantisa = b.parts.mantisa;
result.parts.fraction = b.parts.fraction;
result.parts.exp = b.parts.exp;
return result;
};
64,7 → 64,7
result.binary = FLOAT32_NAN;
return result;
}
result.parts.mantisa = a.parts.mantisa;
result.parts.fraction = a.parts.fraction;
result.parts.exp = a.parts.exp;
return result;
}
75,7 → 75,7
result.binary = FLOAT32_NAN;
return result;
}
result.parts.mantisa = b.parts.mantisa;
result.parts.fraction = b.parts.fraction;
result.parts.exp = b.parts.exp;
return result;
}
95,44 → 95,44
if (exp < 0) {
/* FIXME: underflow */
/* return signed zero */
result.parts.mantisa = 0x0;
result.parts.fraction = 0x0;
result.parts.exp = 0x0;
return result;
};
mant1 = a.parts.mantisa;
frac1 = a.parts.fraction;
if (a.parts.exp > 0) {
mant1 |= FLOAT32_HIDDEN_BIT_MASK;
frac1 |= FLOAT32_HIDDEN_BIT_MASK;
} else {
++exp;
};
mant2 = b.parts.mantisa;
frac2 = b.parts.fraction;
 
if (b.parts.exp > 0) {
mant2 |= FLOAT32_HIDDEN_BIT_MASK;
frac2 |= FLOAT32_HIDDEN_BIT_MASK;
} else {
++exp;
};
 
mant1 <<= 1; /* one bit space for rounding */
frac1 <<= 1; /* one bit space for rounding */
 
mant1 = mant1 * mant2;
frac1 = frac1 * frac2;
/* round and return */
while ((exp < FLOAT32_MAX_EXPONENT) && (mant1 >= ( 1 << (FLOAT32_MANTISA_SIZE + 2)))) {
/* 23 bits of mantisa + one more for hidden bit (all shifted 1 bit left)*/
while ((exp < FLOAT32_MAX_EXPONENT) && (frac1 >= ( 1 << (FLOAT32_FRACTION_SIZE + 2)))) {
/* 23 bits of fraction + one more for hidden bit (all shifted 1 bit left)*/
++exp;
mant1 >>= 1;
frac1 >>= 1;
};
 
/* rounding */
//++mant1; /* FIXME: not works - without it is ok */
mant1 >>= 1; /* shift off rounding space */
/* ++frac1; FIXME: not works - without it is ok */
frac1 >>= 1; /* shift off rounding space */
if ((exp < FLOAT32_MAX_EXPONENT) && (mant1 >= (1 << (FLOAT32_MANTISA_SIZE + 1)))) {
if ((exp < FLOAT32_MAX_EXPONENT) && (frac1 >= (1 << (FLOAT32_FRACTION_SIZE + 1)))) {
++exp;
mant1 >>= 1;
frac1 >>= 1;
};
 
if (exp >= FLOAT32_MAX_EXPONENT ) {
139,28 → 139,28
/* TODO: fix overflow */
/* return infinity*/
result.parts.exp = FLOAT32_MAX_EXPONENT;
result.parts.mantisa = 0x0;
result.parts.fraction = 0x0;
return result;
}
exp -= FLOAT32_MANTISA_SIZE;
exp -= FLOAT32_FRACTION_SIZE;
 
if (exp <= FLOAT32_MANTISA_SIZE) {
if (exp <= FLOAT32_FRACTION_SIZE) {
/* denormalized number */
mant1 >>= 1; /* denormalize */
while ((mant1 > 0) && (exp < 0)) {
mant1 >>= 1;
frac1 >>= 1; /* denormalize */
while ((frac1 > 0) && (exp < 0)) {
frac1 >>= 1;
++exp;
};
if (mant1 == 0) {
if (frac1 == 0) {
/* FIXME : underflow */
result.parts.exp = 0;
result.parts.mantisa = 0;
result.parts.fraction = 0;
return result;
};
};
result.parts.exp = exp;
result.parts.mantisa = mant1 & ( (1 << FLOAT32_MANTISA_SIZE) - 1);
result.parts.fraction = frac1 & ( (1 << FLOAT32_FRACTION_SIZE) - 1);
return result;
172,7 → 172,7
float64 mulFloat64(float64 a, float64 b)
{
float64 result;
__u64 mant1, mant2;
__u64 frac1, frac2;
__s32 exp;
 
result.parts.sign = a.parts.sign ^ b.parts.sign;
180,12 → 180,12
if (isFloat64NaN(a) || isFloat64NaN(b) ) {
/* TODO: fix SigNaNs */
if (isFloat64SigNaN(a)) {
result.parts.mantisa = a.parts.mantisa;
result.parts.fraction = a.parts.fraction;
result.parts.exp = a.parts.exp;
return result;
};
if (isFloat64SigNaN(b)) { /* TODO: fix SigNaN */
result.parts.mantisa = b.parts.mantisa;
result.parts.fraction = b.parts.fraction;
result.parts.exp = b.parts.exp;
return result;
};
200,7 → 200,7
result.binary = FLOAT64_NAN;
return result;
}
result.parts.mantisa = a.parts.mantisa;
result.parts.fraction = a.parts.fraction;
result.parts.exp = a.parts.exp;
return result;
}
211,7 → 211,7
result.binary = FLOAT64_NAN;
return result;
}
result.parts.mantisa = b.parts.mantisa;
result.parts.fraction = b.parts.fraction;
result.parts.exp = b.parts.exp;
return result;
}
231,32 → 231,32
if (exp < 0) {
/* FIXME: underflow */
/* return signed zero */
result.parts.mantisa = 0x0;
result.parts.fraction = 0x0;
result.parts.exp = 0x0;
return result;
};
mant1 = a.parts.mantisa;
frac1 = a.parts.fraction;
if (a.parts.exp > 0) {
mant1 |= FLOAT64_HIDDEN_BIT_MASK;
frac1 |= FLOAT64_HIDDEN_BIT_MASK;
} else {
++exp;
};
mant2 = b.parts.mantisa;
frac2 = b.parts.fraction;
 
if (b.parts.exp > 0) {
mant2 |= FLOAT64_HIDDEN_BIT_MASK;
frac2 |= FLOAT64_HIDDEN_BIT_MASK;
} else {
++exp;
};
 
mant1 <<= 1; /* one bit space for rounding */
frac1 <<= 1; /* one bit space for rounding */
 
mul64integers(mant1, mant2, &mant1, &mant2);
mul64integers(frac1, frac2, &frac1, &frac2);
 
/* round and return */
/* FIXME: ugly soulution is to shift whole mant2 >> as in 32bit version
/* FIXME: ugly soulution is to shift whole frac2 >> as in 32bit version
* Here is is more slower because we have to shift two numbers with carry
* Better is find first nonzero bit and make only one shift
* Third version is to shift both numbers a bit to right and result will be then
263,25 → 263,25
* placed in higher part of result. Then lower part will be good only for rounding.
*/
while ((exp < FLOAT64_MAX_EXPONENT) && (mant2 > 0 )) {
mant1 >>= 1;
mant1 &= ((mant2 & 0x1) << 63);
mant2 >>= 1;
while ((exp < FLOAT64_MAX_EXPONENT) && (frac2 > 0 )) {
frac1 >>= 1;
frac1 &= ((frac2 & 0x1) << 63);
frac2 >>= 1;
++exp;
}
while ((exp < FLOAT64_MAX_EXPONENT) && (mant1 >= ( (__u64)1 << (FLOAT64_MANTISA_SIZE + 2)))) {
while ((exp < FLOAT64_MAX_EXPONENT) && (frac1 >= ( (__u64)1 << (FLOAT64_FRACTION_SIZE + 2)))) {
++exp;
mant1 >>= 1;
frac1 >>= 1;
};
 
/* rounding */
//++mant1; /* FIXME: not works - without it is ok */
mant1 >>= 1; /* shift off rounding space */
/* ++frac1; FIXME: not works - without it is ok */
frac1 >>= 1; /* shift off rounding space */
if ((exp < FLOAT64_MAX_EXPONENT) && (mant1 >= ((__u64)1 << (FLOAT64_MANTISA_SIZE + 1)))) {
if ((exp < FLOAT64_MAX_EXPONENT) && (frac1 >= ((__u64)1 << (FLOAT64_FRACTION_SIZE + 1)))) {
++exp;
mant1 >>= 1;
frac1 >>= 1;
};
 
if (exp >= FLOAT64_MAX_EXPONENT ) {
288,28 → 288,28
/* TODO: fix overflow */
/* return infinity*/
result.parts.exp = FLOAT64_MAX_EXPONENT;
result.parts.mantisa = 0x0;
result.parts.fraction = 0x0;
return result;
}
exp -= FLOAT64_MANTISA_SIZE;
exp -= FLOAT64_FRACTION_SIZE;
 
if (exp <= FLOAT64_MANTISA_SIZE) {
if (exp <= FLOAT64_FRACTION_SIZE) {
/* denormalized number */
mant1 >>= 1; /* denormalize */
while ((mant1 > 0) && (exp < 0)) {
mant1 >>= 1;
frac1 >>= 1; /* denormalize */
while ((frac1 > 0) && (exp < 0)) {
frac1 >>= 1;
++exp;
};
if (mant1 == 0) {
if (frac1 == 0) {
/* FIXME : underflow */
result.parts.exp = 0;
result.parts.mantisa = 0;
result.parts.fraction = 0;
return result;
};
};
result.parts.exp = exp;
result.parts.mantisa = mant1 & ( ((__u64)1 << FLOAT64_MANTISA_SIZE) - 1);
result.parts.fraction = frac1 & ( ((__u64)1 << FLOAT64_FRACTION_SIZE) - 1);
return result;
338,8 → 338,8
high = a * b;
 
middle1 += middle2;
high += ((__u64)(middle1 < middle2) << 32) + middle1>>32;
middle1 << 32;
high += ((__u64)(middle1 < middle2) << 32) + (middle1 >> 32);
middle1 <<= 32;
low += middle1;
high += (low < middle1);
*lo = low;