diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2024-11-05 10:09:53 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2024-11-05 10:09:53 +0000 |
commit | 0c587f13397a306f7ad4f8b0b7cb9184488012b5 (patch) | |
tree | a3cd06c572e82c828fcbcca8764a9a63fa216b4e /target/mips | |
parent | d1ff996788a41280e2e0213b9571afeca4d6ca90 (diff) | |
download | qemu-0c587f13397a306f7ad4f8b0b7cb9184488012b5.zip qemu-0c587f13397a306f7ad4f8b0b7cb9184488012b5.tar.gz qemu-0c587f13397a306f7ad4f8b0b7cb9184488012b5.tar.bz2 |
target/mips: Explicitly set 2-NaN propagation rule
Set the 2-NaN propagation rule explicitly in the float_status words
we use.
For active_fpu.fp_status, we do this in a new fp_reset() function
which mirrors the existing msa_reset() function in doing "first call
restore to set the fp status parts that depend on CPU state, then set
the fp status parts that are constant".
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20241025141254.2141506-5-peter.maydell@linaro.org
Diffstat (limited to 'target/mips')
-rw-r--r-- | target/mips/cpu.c | 2 | ||||
-rw-r--r-- | target/mips/fpu_helper.h | 22 | ||||
-rw-r--r-- | target/mips/msa.c | 17 |
3 files changed, 40 insertions, 1 deletions
diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 9724e71..d0a43b6 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -407,9 +407,9 @@ static void mips_cpu_reset_hold(Object *obj, ResetType type) } msa_reset(env); + fp_reset(env); compute_hflags(env); - restore_fp_status(env); restore_pamask(env); cs->exception_index = EXCP_NONE; diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h index ad1116e..7c3c789 100644 --- a/target/mips/fpu_helper.h +++ b/target/mips/fpu_helper.h @@ -44,6 +44,28 @@ static inline void restore_fp_status(CPUMIPSState *env) restore_snan_bit_mode(env); } +static inline void fp_reset(CPUMIPSState *env) +{ + restore_fp_status(env); + + /* + * According to MIPS specifications, if one of the two operands is + * a sNaN, a new qNaN has to be generated. This is done in + * floatXX_silence_nan(). For qNaN inputs the specifications + * says: "When possible, this QNaN result is one of the operand QNaN + * values." In practice it seems that most implementations choose + * the first operand if both operands are qNaN. In short this gives + * the following rules: + * 1. A if it is signaling + * 2. B if it is signaling + * 3. A (quiet) + * 4. B (quiet) + * A signaling NaN is always silenced before returning it. + */ + set_float_2nan_prop_rule(float_2nan_prop_s_ab, + &env->active_fpu.fp_status); +} + /* MSA */ enum CPUMIPSMSADataFormat { diff --git a/target/mips/msa.c b/target/mips/msa.c index 61f1a9a..9dffc42 100644 --- a/target/mips/msa.c +++ b/target/mips/msa.c @@ -49,6 +49,23 @@ void msa_reset(CPUMIPSState *env) set_float_detect_tininess(float_tininess_after_rounding, &env->active_tc.msa_fp_status); + /* + * According to MIPS specifications, if one of the two operands is + * a sNaN, a new qNaN has to be generated. This is done in + * floatXX_silence_nan(). For qNaN inputs the specifications + * says: "When possible, this QNaN result is one of the operand QNaN + * values." In practice it seems that most implementations choose + * the first operand if both operands are qNaN. In short this gives + * the following rules: + * 1. A if it is signaling + * 2. B if it is signaling + * 3. A (quiet) + * 4. B (quiet) + * A signaling NaN is always silenced before returning it. + */ + set_float_2nan_prop_rule(float_2nan_prop_s_ab, + &env->active_tc.msa_fp_status); + /* clear float_status exception flags */ set_float_exception_flags(0, &env->active_tc.msa_fp_status); |