/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; |