@ -453,78 +453,29 @@ uint64_t helper_cvtqs(CPUAlphaState *env, uint64_t a)
static uint64_t do_cvttq ( CPUAlphaState * env , uint64_t a , int roundmode )
{
uint64_t frac , ret = 0 ;
uint32_t exp , sign , exc = 0 ;
int shift ;
float64 fa ;
int64_t ret ;
uint32_t exc ;
sign = ( a > > 63 ) ;
exp = ( uint32_t ) ( a > > 52 ) & 0x7ff ;
frac = a & 0xfffffffffffffull ;
fa = t_to_float64 ( a ) ;
ret = float64_to_int64_modulo ( fa , roundmode , & FP_STATUS ) ;
if ( exp = = 0 ) {
if ( unlikely ( frac ! = 0 ) & & ! env - > fp_status . flush_inputs_to_zero ) {
goto do_underflow ;
}
} else if ( exp = = 0x7ff ) {
exc = FPCR_INV ;
} else {
/* Restore implicit bit. */
frac | = 0x10000000000000ull ;
shift = exp - 1023 - 52 ;
if ( shift > = 0 ) {
/* In this case the number is so large that we must shift
the fraction left . There is no rounding to do . */
if ( shift < 64 ) {
ret = frac < < shift ;
}
/* Check for overflow. Note the special case of -0x1p63. */
if ( shift > = 11 & & a ! = 0xC3E0000000000000ull ) {
exc = FPCR_IOV | FPCR_INE ;
}
} else {
uint64_t round ;
/* In this case the number is smaller than the fraction as
represented by the 52 bit number . Here we must think
about rounding the result . Handle this by shifting the
fractional part of the number into the high bits of ROUND .
This will let us efficiently handle round - to - nearest . */
shift = - shift ;
if ( shift < 63 ) {
ret = frac > > shift ;
round = frac < < ( 64 - shift ) ;
} else {
/* The exponent is so small we shift out everything.
Leave a sticky bit for proper rounding below . */
do_underflow :
round = 1 ;
}
exc = get_float_exception_flags ( & FP_STATUS ) ;
if ( unlikely ( exc ) ) {
set_float_exception_flags ( 0 , & FP_STATUS ) ;
if ( round ) {
exc = FPCR_INE ;
switch ( roundmode ) {
case float_round_nearest_even :
if ( round = = ( 1ull < < 63 ) ) {
/* Fraction is exactly 0.5; round to even. */
ret + = ( ret & 1 ) ;
} else if ( round > ( 1ull < < 63 ) ) {
ret + = 1 ;
}
break ;
case float_round_to_zero :
break ;
case float_round_up :
ret + = 1 - sign ;
break ;
case float_round_down :
ret + = sign ;
break ;
}
/* We need to massage the resulting exceptions. */
if ( exc & float_flag_invalid_cvti ) {
/* Overflow, either normal or infinity. */
if ( float64_is_infinity ( fa ) ) {
exc = FPCR_INV ;
} else {
exc = FPCR_IOV | FPCR_INE ;
}
}
if ( sign ) {
ret = - ret ;
} else if ( exc & float_flag_invalid ) {
exc = FPCR_INV ;
} else if ( exc & float_flag_inexact ) {
exc = FPCR_INE ;
}
}
env - > error_code = exc ;