On Fri, 8 May 2026 at 00:49, Richard Henderson
<[email protected]> wrote:
>
> Signed-off-by: Richard Henderson <[email protected]>

> +static void fp8_finish_fpst(float_status *orig, float_status *tmp)
> +{
> +    int e = get_float_exception_flags(tmp);
> +    float_raise(e & ~float_flag_input_denormal_used, orig);
> +}
> +
>  static void fp8_finish(CPUARMState *env, FP8Context *c)
>  {
> -    int new_flags = get_float_exception_flags(&c->stat);
> -
> -    new_flags &= ~float_flag_input_denormal_used;
> -    float_raise(new_flags, &env->vfp.fp_status[c->fpst]);
> +    fp8_finish_fpst(&env->vfp.fp_status[c->fpst], &c->stat);
>  }

> +static void fp8_mul_finish(CPUARMState *env, FP8MulContext *c)
> +{
> +    fp8_finish_fpst(&env->vfp.fp_status[FPST_A64], &c->stat);
> +}

The Arm ARM 1.5.5 says that FP8 convert insns and FP8 mul insns
have slightly different fp exception flag behaviour:
 * neither updates FPSR.IDC (input-denormal)
 * convert insns do update FPSR.{IOC, IXC, UFC} for Invalid,
   Inexact, Underflow
 * mul insns do not update IOC, IXC, UFC

Perhaps squash in something like this ?

--- a/target/arm/tcg/fp8_helper.c
+++ b/target/arm/tcg/fp8_helper.c
@@ -55,15 +55,18 @@ static FP8Context fp8_start(CPUARMState *env, uint32_t desc,
     return ret;
 }

-static void fp8_finish_fpst(float_status *orig, float_status *tmp)
+static void fp8_finish_fpst(float_status *orig, float_status *tmp,
+                            uint16_t squash_flags)
 {
     int e = get_float_exception_flags(tmp);
-    float_raise(e & ~float_flag_input_denormal_used, orig);
+    float_raise(e & ~squash_flags, orig);
 }

 static void fp8_finish(CPUARMState *env, FP8Context *c)
 {
-    fp8_finish_fpst(&env->vfp.fp_status[c->fpst], &c->stat);
+    /* FP8 convert insns don't update FPSR.IDC */
+    fp8_finish_fpst(&env->vfp.fp_status[c->fpst], &c->stat,
+                    float_flag_input_denormal_used);
 }

 static FP8Context fp8_src_start(CPUARMState *env, uint32_t desc, int
scale_mask)
@@ -597,7 +600,13 @@ static FP8MulContext fp8_mul_start(CPUARMState
*env, int scale_mask)

 static void fp8_mul_finish(CPUARMState *env, FP8MulContext *c)
 {
-    fp8_finish_fpst(&env->vfp.fp_status[FPST_A64], &c->stat);
+    /* FP8 multiplies don't update FPSR.{IDC,IOC,IXC,UFC} */
+    fp8_finish_fpst(&env->vfp.fp_status[FPST_A64], &c->stat,
+                    float_flag_input_denormal_used |
+                    float_flag_invalid |
+                    float_flag_inexact |
+                    float_flag_output_denormal_flushed |
+                    float_flag_underflow);
 }

 static FloatParts64 f8dot(uint64_t a, uint64_t b, int n, FP8MulContext *ctx)

thanks
-- PMM

Reply via email to