From 5fa3a975494ee395fef3b28826873520f44b8ce5 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 9 Mar 2018 01:33:15 -0500 Subject: [PATCH] softfloat: use floatx80_infinity in softfloat Since f3218a8 ("softfloat: add floatx80 constants") floatx80_infinity is defined but never used. This patch updates floatx80 functions to use this definition. This allows to define a different default Infinity value on m68k: the m68k FPU defines infinity with all bits set to zero in the mantissa. Backports commit 0f605c889ca3fe9744166ad4149d0dff6dacb696 from qemu --- qemu/aarch64.h | 1 + qemu/aarch64eb.h | 1 + qemu/arm.h | 1 + qemu/armeb.h | 1 + qemu/fpu/softfloat-specialize.h | 14 ++++++++++++ qemu/fpu/softfloat.c | 39 +++++++++++++++++++++------------ qemu/header_gen.py | 1 + qemu/include/fpu/softfloat.h | 13 +++++++++-- qemu/m68k.h | 1 + qemu/mips.h | 1 + qemu/mips64.h | 1 + qemu/mips64el.h | 1 + qemu/mipsel.h | 1 + qemu/powerpc.h | 1 + qemu/sparc.h | 1 + qemu/sparc64.h | 1 + qemu/x86_64.h | 1 + 17 files changed, 64 insertions(+), 16 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 95982fd9..5318722a 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_aarch64 #define floatx80_eq floatx80_eq_aarch64 #define floatx80_eq_quiet floatx80_eq_quiet_aarch64 +#define floatx80_infinity floatx80_infinity_aarch64 #define floatx80_is_quiet_nan floatx80_is_quiet_nan_aarch64 #define floatx80_is_signaling_nan floatx80_is_signaling_nan_aarch64 #define floatx80_le floatx80_le_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 915896ed..8df32930 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_aarch64eb #define floatx80_eq floatx80_eq_aarch64eb #define floatx80_eq_quiet floatx80_eq_quiet_aarch64eb +#define floatx80_infinity floatx80_infinity_aarch64eb #define floatx80_is_quiet_nan floatx80_is_quiet_nan_aarch64eb #define floatx80_is_signaling_nan floatx80_is_signaling_nan_aarch64eb #define floatx80_le floatx80_le_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 573fbf70..2cf2d4bf 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_arm #define floatx80_eq floatx80_eq_arm #define floatx80_eq_quiet floatx80_eq_quiet_arm +#define floatx80_infinity floatx80_infinity_arm #define floatx80_is_quiet_nan floatx80_is_quiet_nan_arm #define floatx80_is_signaling_nan floatx80_is_signaling_nan_arm #define floatx80_le floatx80_le_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 0e1a4787..74620331 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_armeb #define floatx80_eq floatx80_eq_armeb #define floatx80_eq_quiet floatx80_eq_quiet_armeb +#define floatx80_infinity floatx80_infinity_armeb #define floatx80_is_quiet_nan floatx80_is_quiet_nan_armeb #define floatx80_is_signaling_nan floatx80_is_signaling_nan_armeb #define floatx80_le floatx80_le_armeb diff --git a/qemu/fpu/softfloat-specialize.h b/qemu/fpu/softfloat-specialize.h index bc7cc9ad..0ff43734 100644 --- a/qemu/fpu/softfloat-specialize.h +++ b/qemu/fpu/softfloat-specialize.h @@ -177,6 +177,20 @@ floatx80 floatx80_default_nan(float_status *status) return r; } +/*---------------------------------------------------------------------------- +| The pattern for a default generated extended double-precision inf. +*----------------------------------------------------------------------------*/ + +#define floatx80_infinity_high 0x7FFF +#if defined(TARGET_M68K) +#define floatx80_infinity_low LIT64(0x0000000000000000) +#else +#define floatx80_infinity_low LIT64(0x8000000000000000) +#endif + +const floatx80 floatx80_infinity + = make_floatx80_init(floatx80_infinity_high, floatx80_infinity_low); + /*---------------------------------------------------------------------------- | The pattern for a default generated quadruple-precision NaN. *----------------------------------------------------------------------------*/ diff --git a/qemu/fpu/softfloat.c b/qemu/fpu/softfloat.c index a5ed40b6..e1af21f6 100644 --- a/qemu/fpu/softfloat.c +++ b/qemu/fpu/softfloat.c @@ -2615,7 +2615,8 @@ floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign, ) { return packFloatx80( zSign, 0x7FFE, ~ roundMask ); } - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + return packFloatx80(zSign, floatx80_infinity_high, + floatx80_infinity_low); } if ( zExp <= 0 ) { isTiny = @@ -3150,7 +3151,9 @@ floatx80 float32_to_floatx80(float32 a, float_status *status) if (aSig) { return commonNaNToFloatx80(float32ToCommonNaN(a, status), status); } - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + return packFloatx80(aSign, + floatx80_infinity_high, + floatx80_infinity_low); } if ( aExp == 0 ) { if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); @@ -4002,7 +4005,8 @@ floatx80 float64_to_floatx80(float64 a, float_status *status) if (aSig) { return commonNaNToFloatx80( float64ToCommonNaN(a, status), status); } - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + return packFloatx80(aSign, floatx80_infinity_high, + floatx80_infinity_low); } if ( aExp == 0 ) { if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); @@ -4513,10 +4517,7 @@ int64_t floatx80_to_int64(floatx80 a, float_status *status) if ( shiftCount <= 0 ) { if ( shiftCount ) { float_raise(float_flag_invalid, status); - if ( ! aSign - || ( ( aExp == 0x7FFF ) - && ( aSig != LIT64( 0x8000000000000000 ) ) ) - ) { + if (!aSign || floatx80_is_any_nan(a)) { return LIT64( 0x7FFFFFFFFFFFFFFF ); } return (int64_t) LIT64( 0x8000000000000000 ); @@ -4819,7 +4820,9 @@ static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, flag zSign, float_status else if ( expDiff < 0 ) { if ( bExp == 0x7FFF ) { if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN(a, b, status); - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + return packFloatx80(zSign, + floatx80_infinity_high, + floatx80_infinity_low); } if ( aExp == 0 ) ++expDiff; shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); @@ -4893,7 +4896,8 @@ static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, flag zSign, float_status bExpBigger: if ( bExp == 0x7FFF ) { if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status ); - return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) ); + return packFloatx80(zSign ^ 1, floatx80_infinity_high, + floatx80_infinity_low); } if ( aExp == 0 ) ++expDiff; shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); @@ -4998,7 +5002,8 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status) return propagateFloatx80NaN( a, b, status ); } if ( ( bExp | bSig ) == 0 ) goto invalid; - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + return packFloatx80(zSign, floatx80_infinity_high, + floatx80_infinity_low); } if ( bExp == 0x7FFF ) { if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status ); @@ -5007,7 +5012,8 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status) float_raise(float_flag_invalid, status); return floatx80_default_nan(status); } - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + return packFloatx80(zSign, floatx80_infinity_high, + floatx80_infinity_low); } if ( aExp == 0 ) { if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); @@ -5059,7 +5065,8 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status) if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status ); goto invalid; } - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + return packFloatx80(zSign, floatx80_infinity_high, + floatx80_infinity_low); } if ( bExp == 0x7FFF ) { if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status ); @@ -5073,7 +5080,9 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status) return floatx80_default_nan(status); } float_raise(float_flag_divbyzero, status); - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + return packFloatx80(zSign, + floatx80_infinity_high, + floatx80_infinity_low); } normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); } @@ -5892,7 +5901,9 @@ floatx80 float128_to_floatx80(float128 a, float_status *status) if ( aSig0 | aSig1 ) { return commonNaNToFloatx80( float128ToCommonNaN( a, status ), status ); } - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + return packFloatx80(aSign, + floatx80_infinity_high, + floatx80_infinity_low); } if ( aExp == 0 ) { if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 ); diff --git a/qemu/header_gen.py b/qemu/header_gen.py index e37ac3bd..a96bcf96 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -656,6 +656,7 @@ symbols = ( 'floatx80_div', 'floatx80_eq', 'floatx80_eq_quiet', + 'floatx80_infinity', 'floatx80_is_quiet_nan', 'floatx80_is_signaling_nan', 'floatx80_le', diff --git a/qemu/include/fpu/softfloat.h b/qemu/include/fpu/softfloat.h index 7c9e4f64..ddf73c6c 100644 --- a/qemu/include/fpu/softfloat.h +++ b/qemu/include/fpu/softfloat.h @@ -579,6 +579,11 @@ float32 floatx80_to_float32(floatx80, float_status *status); float64 floatx80_to_float64(floatx80, float_status *status); float128 floatx80_to_float128(floatx80, float_status *status); +/*---------------------------------------------------------------------------- +| The pattern for an extended double-precision inf. +*----------------------------------------------------------------------------*/ +extern const floatx80 floatx80_infinity; + /*---------------------------------------------------------------------------- | Software IEC/IEEE extended double-precision operations. *----------------------------------------------------------------------------*/ @@ -619,7 +624,12 @@ static inline floatx80 floatx80_chs(floatx80 a) static inline int floatx80_is_infinity(floatx80 a) { - return (a.high & 0x7fff) == 0x7fff && a.low == 0x8000000000000000LL; +#if defined(TARGET_M68K) + return (a.high & 0x7fff) == floatx80_infinity.high && !(a.low << 1); +#else + return (a.high & 0x7fff) == floatx80_infinity.high && + a.low == floatx80_infinity.low; +#endif } static inline int floatx80_is_neg(floatx80 a) @@ -662,7 +672,6 @@ static inline bool floatx80_invalid_encoding(floatx80 a) #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL) #define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL) #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL) -#define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL) /*---------------------------------------------------------------------------- | Returns the fraction bits of the extended double-precision floating-point diff --git a/qemu/m68k.h b/qemu/m68k.h index 87f5fb50..c249ca29 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_m68k #define floatx80_eq floatx80_eq_m68k #define floatx80_eq_quiet floatx80_eq_quiet_m68k +#define floatx80_infinity floatx80_infinity_m68k #define floatx80_is_quiet_nan floatx80_is_quiet_nan_m68k #define floatx80_is_signaling_nan floatx80_is_signaling_nan_m68k #define floatx80_le floatx80_le_m68k diff --git a/qemu/mips.h b/qemu/mips.h index e430b2dd..d96d752b 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_mips #define floatx80_eq floatx80_eq_mips #define floatx80_eq_quiet floatx80_eq_quiet_mips +#define floatx80_infinity floatx80_infinity_mips #define floatx80_is_quiet_nan floatx80_is_quiet_nan_mips #define floatx80_is_signaling_nan floatx80_is_signaling_nan_mips #define floatx80_le floatx80_le_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index fcd0a36f..837344af 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_mips64 #define floatx80_eq floatx80_eq_mips64 #define floatx80_eq_quiet floatx80_eq_quiet_mips64 +#define floatx80_infinity floatx80_infinity_mips64 #define floatx80_is_quiet_nan floatx80_is_quiet_nan_mips64 #define floatx80_is_signaling_nan floatx80_is_signaling_nan_mips64 #define floatx80_le floatx80_le_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index d0accfe9..d95ced59 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_mips64el #define floatx80_eq floatx80_eq_mips64el #define floatx80_eq_quiet floatx80_eq_quiet_mips64el +#define floatx80_infinity floatx80_infinity_mips64el #define floatx80_is_quiet_nan floatx80_is_quiet_nan_mips64el #define floatx80_is_signaling_nan floatx80_is_signaling_nan_mips64el #define floatx80_le floatx80_le_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 126c0de6..a59be924 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_mipsel #define floatx80_eq floatx80_eq_mipsel #define floatx80_eq_quiet floatx80_eq_quiet_mipsel +#define floatx80_infinity floatx80_infinity_mipsel #define floatx80_is_quiet_nan floatx80_is_quiet_nan_mipsel #define floatx80_is_signaling_nan floatx80_is_signaling_nan_mipsel #define floatx80_le floatx80_le_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index e904581a..95d124a5 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_powerpc #define floatx80_eq floatx80_eq_powerpc #define floatx80_eq_quiet floatx80_eq_quiet_powerpc +#define floatx80_infinity floatx80_infinity_powerpc #define floatx80_is_quiet_nan floatx80_is_quiet_nan_powerpc #define floatx80_is_signaling_nan floatx80_is_signaling_nan_powerpc #define floatx80_le floatx80_le_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index da4a62f4..39b5d139 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_sparc #define floatx80_eq floatx80_eq_sparc #define floatx80_eq_quiet floatx80_eq_quiet_sparc +#define floatx80_infinity floatx80_infinity_sparc #define floatx80_is_quiet_nan floatx80_is_quiet_nan_sparc #define floatx80_is_signaling_nan floatx80_is_signaling_nan_sparc #define floatx80_le floatx80_le_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 4a10acb1..12cfaff3 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_sparc64 #define floatx80_eq floatx80_eq_sparc64 #define floatx80_eq_quiet floatx80_eq_quiet_sparc64 +#define floatx80_infinity floatx80_infinity_sparc64 #define floatx80_is_quiet_nan floatx80_is_quiet_nan_sparc64 #define floatx80_is_signaling_nan floatx80_is_signaling_nan_sparc64 #define floatx80_le floatx80_le_sparc64 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index fd0631c0..077ec293 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -650,6 +650,7 @@ #define floatx80_div floatx80_div_x86_64 #define floatx80_eq floatx80_eq_x86_64 #define floatx80_eq_quiet floatx80_eq_quiet_x86_64 +#define floatx80_infinity floatx80_infinity_x86_64 #define floatx80_is_quiet_nan floatx80_is_quiet_nan_x86_64 #define floatx80_is_signaling_nan floatx80_is_signaling_nan_x86_64 #define floatx80_le floatx80_le_x86_64