aboutsummaryrefslogtreecommitdiff
path: root/fpu
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2011-04-20 13:04:22 +0200
committerAurelien Jarno <aurelien@aurel32.net>2011-04-25 11:18:32 +0200
commite2f422047b6fd04c28630f80ab1161dbce07c6b7 (patch)
tree9e8d1773ccd9f59f866f8d27e19dd28d8885d0e4 /fpu
parentda26fdc3145fc990762133beb8ad6bd67742a147 (diff)
downloadqemu-arm-e2f422047b6fd04c28630f80ab1161dbce07c6b7.tar.gz
softfloat: fix floatx80 handling of NaN
The floatx80 format uses an explicit bit that should be taken into account when converting to and from commonNaN format. When converting to commonNaN, the explicit bit should be removed if it is a 1, and a default NaN should be used if it is 0. When converting from commonNan, the explicit bit should be added. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'fpu')
-rw-r--r--fpu/softfloat-specialize.h23
1 files changed, 16 insertions, 7 deletions
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index b1101872af..9d68aae9d5 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -603,9 +603,15 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
commonNaNT z;
if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
- z.sign = a.high>>15;
- z.low = 0;
- z.high = a.low;
+ if ( a.low >> 63 ) {
+ z.sign = a.high >> 15;
+ z.low = 0;
+ z.high = a.low << 1;
+ } else {
+ z.sign = floatx80_default_nan_high >> 15;
+ z.low = 0;
+ z.high = floatx80_default_nan_low << 1;
+ }
return z;
}
@@ -624,11 +630,14 @@ static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
return z;
}
- if (a.high)
- z.low = a.high;
- else
+ if (a.high >> 1) {
+ z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
+ z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
+ } else {
z.low = floatx80_default_nan_low;
- z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
+ z.high = floatx80_default_nan_high;
+ }
+
return z;
}