aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2024-12-11 15:31:09 +0000
committerPeter Maydell <peter.maydell@linaro.org>2024-12-11 15:31:09 +0000
commit9778115ed780c8d8b027dea4125afb3890511797 (patch)
tree7c801f1d23815ab0f712b188700aef7b94b32db2
parent2da7553f2ee818e98e69136ab02106f3bccddf68 (diff)
downloadqemu-9778115ed780c8d8b027dea4125afb3890511797.zip
qemu-9778115ed780c8d8b027dea4125afb3890511797.tar.gz
qemu-9778115ed780c8d8b027dea4125afb3890511797.tar.bz2
softfloat: Sink frac_cmp in parts_pick_nan until needed
Move the fractional comparison to the end of the float_2nan_prop_x87 case. This is not required for any other 2nan propagation rule. Reorganize the x87 case itself to break out of the switch when the fractional comparison is not required. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20241203203949.483774-11-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--fpu/softfloat-parts.c.inc19
1 files changed, 9 insertions, 10 deletions
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 3c77dcb..abe24ae 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -52,11 +52,6 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
return a;
}
- cmp = frac_cmp(a, b);
- if (cmp == 0) {
- cmp = a->sign < b->sign;
- }
-
switch (s->float_2nan_prop_rule) {
case float_2nan_prop_s_ab:
if (have_snan) {
@@ -89,20 +84,24 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
* return the NaN with the positive sign bit (if any).
*/
if (is_snan(a->cls)) {
- if (is_snan(b->cls)) {
- which = cmp > 0 ? 0 : 1;
- } else {
+ if (!is_snan(b->cls)) {
which = is_qnan(b->cls) ? 1 : 0;
+ break;
}
} else if (is_qnan(a->cls)) {
if (is_snan(b->cls) || !is_qnan(b->cls)) {
which = 0;
- } else {
- which = cmp > 0 ? 0 : 1;
+ break;
}
} else {
which = 1;
+ break;
+ }
+ cmp = frac_cmp(a, b);
+ if (cmp == 0) {
+ cmp = a->sign < b->sign;
}
+ which = cmp > 0 ? 0 : 1;
break;
default:
g_assert_not_reached();