On Tue, 19 May 2026 at 14:27, Peter Maydell <[email protected]> wrote:
> If we do take this approach we also need something like:
>
> --- a/fpu/softfloat-parts.c.inc
> +++ b/fpu/softfloat-parts.c.inc
> @@ -288,6 +288,7 @@ static void
> partsN(uncanon_e4m3_overflow)(FloatPartsN *p, float_status *s,
>          p->frac_hi = E4M3_NORMAL_FRAC_MAX;
>      } else {
>          *p = partsN(default_nan)(s);
> +        fracN(allones)(p);
>      }
>  }
>
> because the NaN value from uncanon_e4m3_overflow isn't passed
> through the NaN handling part of uncanon.

This isn't sufficient for the e4m3_overflow case, because we
need to return a NaN with the sign of the input. In the
Arm pseudocode FP8Round() calls FP8Infinity() for the overflow
case for both E4M3 and E5M2; for E5M2 that function returns the
format's Infinity representation, but for E4M3 as there is no
Infinity it returns the NaN with the sign of the input.

diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index d267bb4bbd..efd130bf16 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -287,7 +287,9 @@ static void
partsN(uncanon_e4m3_overflow)(FloatPartsN *p, float_status *s,
         p->exp = fmt->exp_max;
         p->frac_hi = E4M3_NORMAL_FRAC_MAX;
     } else {
-        *p = partsN(default_nan)(s);
+        /* SNaN with sign of input */
+        p->cls = float_class_snan;
+        p->exp = INT_MAX;
+        fracN(allones)(p);
     }
 }

gives the right answers but IDK if riscv wants this behaviour
or some other one.

-- PMM

Reply via email to