mirror of https://gitee.com/openkylin/qemu.git
softfloat: fix default-NaN mode
When the default-NaN mode is enabled, it should return the default NaN value, but it should anyway raise the invalid operation flag if one of the operand is an sNaN. I have checked that this behavior matches the ARM and SH4 manuals, as well as real SH4 hardware. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
e90877507e
commit
102016020b
|
@ -278,9 +278,6 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
|
|||
flag aIsLargerSignificand;
|
||||
bits32 av, bv;
|
||||
|
||||
if ( STATUS(default_nan_mode) )
|
||||
return float32_default_nan;
|
||||
|
||||
aIsQuietNaN = float32_is_quiet_nan( a );
|
||||
aIsSignalingNaN = float32_is_signaling_nan( a );
|
||||
bIsQuietNaN = float32_is_quiet_nan( b );
|
||||
|
@ -290,6 +287,9 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
|
|||
|
||||
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
|
||||
|
||||
if ( STATUS(default_nan_mode) )
|
||||
return float32_default_nan;
|
||||
|
||||
if ((bits32)(av<<1) < (bits32)(bv<<1)) {
|
||||
aIsLargerSignificand = 0;
|
||||
} else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
|
||||
|
@ -423,9 +423,6 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
|
|||
flag aIsLargerSignificand;
|
||||
bits64 av, bv;
|
||||
|
||||
if ( STATUS(default_nan_mode) )
|
||||
return float64_default_nan;
|
||||
|
||||
aIsQuietNaN = float64_is_quiet_nan( a );
|
||||
aIsSignalingNaN = float64_is_signaling_nan( a );
|
||||
bIsQuietNaN = float64_is_quiet_nan( b );
|
||||
|
@ -435,6 +432,9 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
|
|||
|
||||
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
|
||||
|
||||
if ( STATUS(default_nan_mode) )
|
||||
return float64_default_nan;
|
||||
|
||||
if ((bits64)(av<<1) < (bits64)(bv<<1)) {
|
||||
aIsLargerSignificand = 0;
|
||||
} else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
|
||||
|
@ -574,12 +574,6 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
|
|||
flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
|
||||
flag aIsLargerSignificand;
|
||||
|
||||
if ( STATUS(default_nan_mode) ) {
|
||||
a.low = floatx80_default_nan_low;
|
||||
a.high = floatx80_default_nan_high;
|
||||
return a;
|
||||
}
|
||||
|
||||
aIsQuietNaN = floatx80_is_quiet_nan( a );
|
||||
aIsSignalingNaN = floatx80_is_signaling_nan( a );
|
||||
bIsQuietNaN = floatx80_is_quiet_nan( b );
|
||||
|
@ -587,6 +581,12 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
|
|||
|
||||
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
|
||||
|
||||
if ( STATUS(default_nan_mode) ) {
|
||||
a.low = floatx80_default_nan_low;
|
||||
a.high = floatx80_default_nan_high;
|
||||
return a;
|
||||
}
|
||||
|
||||
if (a.low < b.low) {
|
||||
aIsLargerSignificand = 0;
|
||||
} else if (b.low < a.low) {
|
||||
|
@ -719,12 +719,6 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
|
|||
flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
|
||||
flag aIsLargerSignificand;
|
||||
|
||||
if ( STATUS(default_nan_mode) ) {
|
||||
a.low = float128_default_nan_low;
|
||||
a.high = float128_default_nan_high;
|
||||
return a;
|
||||
}
|
||||
|
||||
aIsQuietNaN = float128_is_quiet_nan( a );
|
||||
aIsSignalingNaN = float128_is_signaling_nan( a );
|
||||
bIsQuietNaN = float128_is_quiet_nan( b );
|
||||
|
@ -732,6 +726,12 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
|
|||
|
||||
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
|
||||
|
||||
if ( STATUS(default_nan_mode) ) {
|
||||
a.low = float128_default_nan_low;
|
||||
a.high = float128_default_nan_high;
|
||||
return a;
|
||||
}
|
||||
|
||||
if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
|
||||
aIsLargerSignificand = 0;
|
||||
} else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
|
||||
|
|
Loading…
Reference in New Issue