Code:
int_t alup__mul( alup_t const * const _NUM, alup_t const * const _VAL, void *_cpy, void *_tmp )
{
if ( alup_floating( _NUM ) || alup_floating( _VAL ) )
{
alup_t _DST, _SRC;
ssize_t exp, dexp, sexp, dbias, sbias, bits = _NUM->bits;
bool_t dneg, sneg;
/* Ensure dealing with just floating numbers */
alu_puts("Before Move");
alup_print( _NUM, 0, 1 );
alup_init_floating( _DST, _tmp, bits * 2 );
alup_mov( &_DST, _NUM );
alu_puts("After Move");
alup_print( &_DST, 0, 1 );
alup_init_floating( _SRC, _NUM->data, bits );
_SRC.upto = _NUM->upto;
_SRC.last = _NUM->last;
_SRC.from = _NUM->from;
alup_mov( &_SRC, _VAL );
dneg = alup_below0( &_DST );
sneg = alup_below0( &_SRC );
dexp = alup_get_exponent( &_DST );
sexp = alup_get_exponent( &_SRC );
if ( !dexp || !sexp )
{
alup_set( _NUM, 0 );
alup_set_sign( &_DST, dneg != sneg );
return 0;
}
dbias = alup_get_exponent_bias( &_DST );
sbias = alup_get_exponent_bias( &_SRC );
exp = IFTRUE( dexp, dexp - dbias ) + IFTRUE( sexp, sexp - sbias );
if ( exp >= dbias )
{
alu_puts("MUL 1");
(void)alup_set_fltinf( _NUM, dneg != sneg );
return ERANGE;
}
else
{
size_t mov;
ssize_t dmov, smov;
alup_t _DEXP, _SEXP, _DMAN, _SMAN, __DST, __SRC, _DINFER, _SINFER;
alub_t final, d1st, s1st, dinfer, sinfer;
alup_init_exponent( &_DST, _DEXP );
alup_init_exponent( &_SRC, _SEXP );
alup_set( &_DEXP, !!dexp );
alup_set( &_SEXP, !!sexp );
alup_init_mantissa( &_DST, _DMAN );
alup_init_mantissa( &_SRC, _SMAN );
__DST = _DST;
__DST.mdig = 0;
__DST.sign = false;
__SRC = _SRC;
__SRC.mdig = 0;
__SRC.sign = false;
/* Set position data of assumed bits */
_DINFER = __DST;
_SINFER = __SRC;
_DINFER.from = _DEXP.from;
_SINFER.from = _SEXP.from;
_DINFER.bits = _DINFER.upto - _DINFER.from;
_SINFER.bits = _SINFER.upto - _SINFER.from;
dinfer = alup_bit( &_DINFER, _DINFER.from );
sinfer = alup_bit( &_SINFER, _SINFER.from );
/* Insert assumed bits */
alup_set( &_DINFER, 0 );
alup_set( &_SINFER, 0 );
alub_set_val( dinfer, !!dexp );
alub_set_val( sinfer, !!sexp );
/* Determine how far to move mantissa to right */
d1st = alup_first_bit_with_val( &_DMAN, 1 );
s1st = alup_first_bit_with_val( &_SMAN, 1 );
dmov = d1st.bit - __DST.from;
smov = s1st.bit - __SRC.from;
/* Remove useless 0s */
alu_puts("Before 1st Shift");
alup_print( &_DST, 0, 1 );
(void)alup__shr_int2int( &__DST, dmov );
(void)alup__shr_int2int( &__SRC, smov );
alu_puts("After 1st Shift");
alup_print( &_DST, 0, 1 );
exp += (_DEXP.from - d1st.bit) + (_SEXP.from - s1st.bit) + !!dexp + !!sexp;
alu_puts("Before Multiply");
alup_print( &_DST, 0, 1 );
(void)alup__mul_int2int( &__DST, &__SRC, _cpy );
alu_puts("After Multiply");
alup_print( &_DST, 0, 1 );
/* Normalise */
final = alup_final_bit_with_val( &__DST, 1 );
alu_puts("Before 2nd Shift");
alup_print( &_DST, 0, 1 );
if ( final.bit > _DEXP.from )
{
alu_puts("final.bit > _DEXP.from");
mov = final.bit - _DEXP.from;
//exp += mov;
alup__shr_int2int( &__DST, mov );
}
else
{
alu_puts("final.bit < _DEXP.from");
mov = _DEXP.from - final.bit;
//exp -= mov;
alup__shl_int2int( &__DST, mov );
}
alu_puts("After 2nd Shift");
alup_print( &_DST, 0, 1 );
/* Mantissa is in place so all we need to do is set the exponent
* and sign */
alup_set_exponent( &_DST, exp + dbias );
alu_puts("After Setting Exponent");
alup_print( &_DST, 0, 1 );
alup_set_sign( &_DST, dneg != sneg );
alu_puts("After Setting Sign");
alup_print( &_DST, 0, 1 );
return alup_mov( _NUM, &_DST );
}
}
return alup__mul_int2int( _NUM, _VAL, _cpy );
}
Any ideas?