mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-11 23:27:43 +00:00
softfloat: do not return pseudo-denormal from floatx80 remainder
The floatx80 remainder implementation sometimes returns the numerator unchanged when the denominator is sufficiently larger than the numerator. But if the value to be returned unchanged is a pseudo-denormal, that is incorrect. Fix it to normalize the numerator in that case. Signed-off-by: Joseph Myers <joseph@codesourcery.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <alpine.DEB.2.21.2006081655520.23637@digraph.polyomino.org.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
499a2f7b55
commit
b662495dca
@ -5706,7 +5706,7 @@ floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod,
|
||||
float_status *status)
|
||||
{
|
||||
bool aSign, zSign;
|
||||
int32_t aExp, bExp, expDiff;
|
||||
int32_t aExp, bExp, expDiff, aExpOrig;
|
||||
uint64_t aSig0, aSig1, bSig;
|
||||
uint64_t q, term0, term1, alternateASig0, alternateASig1;
|
||||
|
||||
@ -5715,7 +5715,7 @@ floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod,
|
||||
return floatx80_default_nan(status);
|
||||
}
|
||||
aSig0 = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aExpOrig = aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
bSig = extractFloatx80Frac( b );
|
||||
bExp = extractFloatx80Exp( b );
|
||||
@ -5730,6 +5730,13 @@ floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod,
|
||||
if ((uint64_t)(bSig << 1)) {
|
||||
return propagateFloatx80NaN(a, b, status);
|
||||
}
|
||||
if (aExp == 0 && aSig0 >> 63) {
|
||||
/*
|
||||
* Pseudo-denormal argument must be returned in normalized
|
||||
* form.
|
||||
*/
|
||||
return packFloatx80(aSign, 1, aSig0);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
if ( bExp == 0 ) {
|
||||
@ -5749,7 +5756,16 @@ floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod,
|
||||
expDiff = aExp - bExp;
|
||||
aSig1 = 0;
|
||||
if ( expDiff < 0 ) {
|
||||
if ( mod || expDiff < -1 ) return a;
|
||||
if ( mod || expDiff < -1 ) {
|
||||
if (aExp == 1 && aExpOrig == 0) {
|
||||
/*
|
||||
* Pseudo-denormal argument must be returned in
|
||||
* normalized form.
|
||||
*/
|
||||
return packFloatx80(aSign, aExp, aSig0);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
|
||||
expDiff = 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user