Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 803 → Rev 804

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