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