| 1e75d824 | 24-Feb-2025 |
Peter Maydell <peter.maydell@linaro.org> |
fpu: Move m68k_denormal fmt flag into floatx80_behaviour
Currently we compile-time set an 'm68k_denormal' flag in the FloatFmt for floatx80 for m68k. This controls our handling of what the Intel do
fpu: Move m68k_denormal fmt flag into floatx80_behaviour
Currently we compile-time set an 'm68k_denormal' flag in the FloatFmt for floatx80 for m68k. This controls our handling of what the Intel documentation calls a "pseudo-denormal": a value where the exponent field is zero and the explicit integer bit is set.
For x86, the x87 FPU is supposed to accept a pseudo-denormal as input, but never generate one on output. For m68k, these values are permitted on input and may be produced on output.
Replace the flag in the FloatFmt with a flag indicating whether the float format has an explicit bit (which will be true for floatx80 for all targets, and false for every other float type). Then we can gate the handling of these pseudo-denormals on the setting of a floatx80_behaviour flag.
As far as I can see from the code we don't actually handle the x86-mandated "accept on input but don't generate" behaviour, because the handling in partsN(canonicalize) looked at fmt->m68k_denormal. So I have added TODO comments to that effect.
This commit doesn't change any behaviour for any target.
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-9-peter.maydell@linaro.org Message-id: 20250217125055.160887-7-peter.maydell@linaro.org
show more ...
|
| a261d3e3 | 24-Feb-2025 |
Peter Maydell <peter.maydell@linaro.org> |
fpu: Make floatx80 invalid encoding settable at runtime
Because floatx80 has an explicit integer bit, this permits some odd encodings where the integer bit is not set correctly for the floating poin
fpu: Make floatx80 invalid encoding settable at runtime
Because floatx80 has an explicit integer bit, this permits some odd encodings where the integer bit is not set correctly for the floating point value type. In In Intel terminology the categories are: exp == 0, int = 0, mantissa == 0 : zeroes exp == 0, int = 0, mantissa != 0 : denormals exp == 0, int = 1 : pseudo-denormals 0 < exp < 0x7fff, int = 0 : unnormals 0 < exp < 0x7fff, int = 1 : normals exp == 0x7fff, int = 0, mantissa == 0 : pseudo-infinities exp == 0x7fff, int = 1, mantissa == 0 : infinities exp == 0x7fff, int = 0, mantissa != 0 : pseudo-NaNs exp == 0x7fff, int = 1, mantissa == 0 : NaNs
The usual IEEE cases of zero, denormal, normal, inf and NaN are always valid. x87 permits as input also pseudo-denormals. m68k permits all those and also pseudo-infinities, pseudo-NaNs and unnormals.
Currently we have an ifdef in floatx80_invalid_encoding() to select the x86 vs m68k behaviour. Add new floatx80_behaviour flags to select whether pseudo-NaN and unnormal are valid, and use these (plus the existing pseudo_inf_valid flag) to decide whether these encodings are invalid at runtime.
We leave pseudo-denormals as always-valid, since both x86 and m68k accept them.
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-8-peter.maydell@linaro.org Message-id: 20250217125055.160887-6-peter.maydell@linaro.org
show more ...
|
| 765fe845 | 24-Feb-2025 |
Peter Maydell <peter.maydell@linaro.org> |
fpu: Pass float_status to floatx80_invalid_encoding()
The definition of which floatx80 encodings are invalid is target-specific. Currently we handle this with an ifdef, but we would like to defer t
fpu: Pass float_status to floatx80_invalid_encoding()
The definition of which floatx80 encodings are invalid is target-specific. Currently we handle this with an ifdef, but we would like to defer this decision to runtime. In preparation, pass a float_status argument to floatx80_invalid_encoding().
We will change the implementation from ifdef to looking at the status argument in the following 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-7-peter.maydell@linaro.org
show more ...
|
| 44eb32a9 | 24-Feb-2025 |
Peter Maydell <peter.maydell@linaro.org> |
fpu: Make targets specify whether floatx80 Inf can have Int bit clear
In Intel terminology, a floatx80 Infinity with the explicit integer bit clear is a "pseudo-infinity"; for x86 these are not vali
fpu: Make targets specify whether floatx80 Inf can have Int bit clear
In Intel terminology, a floatx80 Infinity with the explicit integer bit clear is a "pseudo-infinity"; for x86 these are not valid infinity values. m68k is looser and does not care whether the Integer bit is set or clear in an infinity.
Move this setting to runtime rather than using an ifdef in floatx80_is_infinity().
Since this was the last use of the floatx80_infinity global constant, we remove it and its definition here.
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-6-peter.maydell@linaro.org Message-id: 20250217125055.160887-5-peter.maydell@linaro.org
show more ...
|
| 9ea6d1f1 | 24-Feb-2025 |
Peter Maydell <peter.maydell@linaro.org> |
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
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
show more ...
|
| 28f13bcc | 01-Feb-2025 |
Peter Maydell <peter.maydell@linaro.org> |
fpu: allow flushing of output denormals to be after rounding
Currently we handle flushing of output denormals in uncanon_normal always before we deal with rounding. This works for architectures tha
fpu: allow flushing of output denormals to be after rounding
Currently we handle flushing of output denormals in uncanon_normal always before we deal with rounding. This works for architectures that detect tininess before rounding, but is usually not the right place when the architecture detects tininess after rounding. For example, for x86 the SDM states that the MXCSR FTZ control bit causes outputs to be flushed to zero "when it detects a floating-point underflow condition". This means that we mustn't flush to zero if the input is such that after rounding it is no longer tiny.
At least one of our guest architectures does underflow detection after rounding but flushing of denormals before rounding (MIPS MSA); this means we need to have a config knob for this that is separate from our existing tininess_before_rounding setting.
Add an ftz_detection flag. For consistency with tininess_before_rounding, we make it default to "detect ftz after rounding"; this means that we need to explicitly set the flag to "detect ftz before rounding" on every existing architecture that sets flush_to_zero, so that this commit has no behaviour change. (This means more code change here but for the long term a less confusing API.)
For several architectures the current behaviour is either definitely or possibly wrong; annotate those with TODO comments. These architectures are definitely wrong (and should detect ftz after rounding): * x86 * Alpha
For these architectures the spec is unclear: * MIPS (for non-MSA) * RX * SH4
PA-RISC makes ftz detection IMPDEF, but we aren't setting the "tininess before rounding" setting that we ought to.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
show more ...
|
| 1c49280f | 24-Jan-2025 |
Peter Maydell <peter.maydell@linaro.org> |
fpu: Fix a comment in softfloat-types.h
In softfloat-types.h a comment documents that if the float_status field flush_to_zero is set then we flush denormalised results to 0 and set the inexact flag.
fpu: Fix a comment in softfloat-types.h
In softfloat-types.h a comment documents that if the float_status field flush_to_zero is set then we flush denormalised results to 0 and set the inexact flag. This isn't correct: the status flag that we set when flush_to_zero causes us to flush an output to zero is float_flag_output_denormal_flushed.
Correct the comment.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250124162836.2332150-22-peter.maydell@linaro.org
show more ...
|
| 7af64d10 | 24-Jan-2025 |
Peter Maydell <peter.maydell@linaro.org> |
fpu: Rename float_flag_output_denormal to float_flag_output_denormal_flushed
Our float_flag_output_denormal exception flag is set when the fpu code flushes an output denormal to zero. Rename it to f
fpu: Rename float_flag_output_denormal to float_flag_output_denormal_flushed
Our float_flag_output_denormal exception flag is set when the fpu code flushes an output denormal to zero. Rename it to float_flag_output_denormal_flushed: * this keeps it parallel with the flag for flushing input denormals, which we just renamed * it makes it clearer that it doesn't mean "set when the output is a denormal"
Commit created with for f in `git grep -l float_flag_output_denormal`; do sed -i -e 's/float_flag_output_denormal/float_flag_output_denormal_flushed/' $f; done
Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250124162836.2332150-21-peter.maydell@linaro.org
show more ...
|
| 7a944c30 | 11-Dec-2024 |
Peter Maydell <peter.maydell@linaro.org> |
softfloat: Allow runtime choice of NaN propagation for muladd
IEEE 758 does not define a fixed rule for which NaN to pick as the result if both operands of a 3-operand fused multiply-add operation a
softfloat: Allow runtime choice of NaN propagation for muladd
IEEE 758 does not define a fixed rule for which NaN to pick as the result if both operands of a 3-operand fused multiply-add operation are NaNs. As a result different architectures have ended up with different rules for propagating NaNs.
QEMU currently hardcodes the NaN propagation logic into the binary because pickNaNMulAdd() has an ifdef ladder for different targets. We want to make the propagation rule instead be selectable at runtime, because: * this will let us have multiple targets in one QEMU binary * the Arm FEAT_AFP architectural feature includes letting the guest select a NaN propagation rule at runtime
In this commit we add an enum for the propagation rule, the field in float_status, and the corresponding getters and setters. We change pickNaNMulAdd to honour this, but because all targets still leave this field at its default 0 value, the fallback logic will pick the rule type with the old ifdef ladder.
It's valid not to set a propagation rule if default_nan_mode is enabled, because in that case there's no need to pick a NaN; all the callers of pickNaNMulAdd() catch this case and skip calling it.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20241202131347.498124-16-peter.maydell@linaro.org
show more ...
|