fpu: Pass float_status to floatx80_is_infinity()

Unlike the other float formats, whether a floatx80 value is
considered to be an Infinity is target-dependent.  (On x86 if the
explicit integer bit is clear this is a "pseudo-infinity" and not a
valid infinity; m68k does not care about the value of the integer
bit.)

Currently we select this target-specific logic at compile time with
an ifdef.  We're going to want to do this at runtime, so change the
floatx80_is_infinity() function to take a float_status.

This commit doesn't change any logic; we'll do that in the
next commit.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20250224111524.1101196-5-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2025-02-24 11:15:16 +00:00
parent 165ce008d7
commit 9ea6d1f141
3 changed files with 13 additions and 11 deletions

View file

@ -996,7 +996,7 @@ static inline floatx80 floatx80_chs(floatx80 a)
return a;
}
static inline bool floatx80_is_infinity(floatx80 a)
static inline bool floatx80_is_infinity(floatx80 a, float_status *status)
{
#if defined(TARGET_M68K)
return (a.high & 0x7fff) == floatx80_infinity.high && !(a.low << 1);

View file

@ -1393,7 +1393,8 @@ void helper_fpatan(CPUX86State *env)
/* Pass this NaN through. */
} else if (floatx80_is_zero(ST1) && !arg0_sign) {
/* Pass this zero through. */
} else if (((floatx80_is_infinity(ST0) && !floatx80_is_infinity(ST1)) ||
} else if (((floatx80_is_infinity(ST0, &env->fp_status) &&
!floatx80_is_infinity(ST1, &env->fp_status)) ||
arg0_exp - arg1_exp >= 80) &&
!arg0_sign) {
/*
@ -1442,8 +1443,8 @@ void helper_fpatan(CPUX86State *env)
rexp = pi_exp;
rsig0 = pi_sig_high;
rsig1 = pi_sig_low;
} else if (floatx80_is_infinity(ST1)) {
if (floatx80_is_infinity(ST0)) {
} else if (floatx80_is_infinity(ST1, &env->fp_status)) {
if (floatx80_is_infinity(ST0, &env->fp_status)) {
if (arg0_sign) {
rexp = pi_34_exp;
rsig0 = pi_34_sig_high;
@ -1462,7 +1463,8 @@ void helper_fpatan(CPUX86State *env)
rexp = pi_2_exp;
rsig0 = pi_2_sig_high;
rsig1 = pi_2_sig_low;
} else if (floatx80_is_infinity(ST0) || arg0_exp - arg1_exp >= 80) {
} else if (floatx80_is_infinity(ST0, &env->fp_status) ||
arg0_exp - arg1_exp >= 80) {
/* ST0 is negative. */
rexp = pi_exp;
rsig0 = pi_sig_high;
@ -1829,7 +1831,7 @@ void helper_fxtract(CPUX86State *env)
}
fpush(env);
ST0 = ST1;
} else if (floatx80_is_infinity(ST0)) {
} else if (floatx80_is_infinity(ST0, &env->fp_status)) {
fpush(env);
ST0 = ST1;
ST1 = floatx80_default_inf(0, &env->fp_status);
@ -2173,7 +2175,7 @@ void helper_fyl2x(CPUX86State *env)
} else if (arg0_sign && !floatx80_is_zero(ST0)) {
float_raise(float_flag_invalid, &env->fp_status);
ST1 = floatx80_default_nan(&env->fp_status);
} else if (floatx80_is_infinity(ST1)) {
} else if (floatx80_is_infinity(ST1, &env->fp_status)) {
FloatRelation cmp = floatx80_compare(ST0, floatx80_one,
&env->fp_status);
switch (cmp) {
@ -2188,7 +2190,7 @@ void helper_fyl2x(CPUX86State *env)
ST1 = floatx80_default_nan(&env->fp_status);
break;
}
} else if (floatx80_is_infinity(ST0)) {
} else if (floatx80_is_infinity(ST0, &env->fp_status)) {
if (floatx80_is_zero(ST1)) {
float_raise(float_flag_invalid, &env->fp_status);
ST1 = floatx80_default_nan(&env->fp_status);
@ -2341,11 +2343,11 @@ void helper_fscale(CPUX86State *env)
float_raise(float_flag_invalid, &env->fp_status);
ST0 = floatx80_silence_nan(ST0, &env->fp_status);
}
} else if (floatx80_is_infinity(ST1) &&
} else if (floatx80_is_infinity(ST1, &env->fp_status) &&
!floatx80_invalid_encoding(ST0) &&
!floatx80_is_any_nan(ST0)) {
if (floatx80_is_neg(ST1)) {
if (floatx80_is_infinity(ST0)) {
if (floatx80_is_infinity(ST0, &env->fp_status)) {
float_raise(float_flag_invalid, &env->fp_status);
ST0 = floatx80_default_nan(&env->fp_status);
} else {

View file

@ -455,7 +455,7 @@ void HELPER(ftst)(CPUM68KState *env, FPReg *val)
if (floatx80_is_any_nan(val->d)) {
cc |= FPSR_CC_A;
} else if (floatx80_is_infinity(val->d)) {
} else if (floatx80_is_infinity(val->d, &env->fp_status)) {
cc |= FPSR_CC_I;
} else if (floatx80_is_zero(val->d)) {
cc |= FPSR_CC_Z;