target/arm: Introduce FPST_ZA, FPST_ZA_F16
Rather than repeatedly copying FPST_FPCR to locals and setting default nan mode, create dedicated float_status. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250704142112.1018902-12-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
afb1bd20df
commit
c994c84d38
3 changed files with 26 additions and 2 deletions
|
|
@ -554,11 +554,15 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type)
|
|||
set_flush_inputs_to_zero(1, &env->vfp.fp_status[FPST_STD]);
|
||||
set_default_nan_mode(1, &env->vfp.fp_status[FPST_STD]);
|
||||
set_default_nan_mode(1, &env->vfp.fp_status[FPST_STD_F16]);
|
||||
set_default_nan_mode(1, &env->vfp.fp_status[FPST_ZA]);
|
||||
set_default_nan_mode(1, &env->vfp.fp_status[FPST_ZA_F16]);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_A32]);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_A64]);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_ZA]);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_STD]);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_A32_F16]);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_A64_F16]);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_ZA_F16]);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_STD_F16]);
|
||||
arm_set_ah_fp_behaviours(&env->vfp.fp_status[FPST_AH]);
|
||||
set_flush_to_zero(1, &env->vfp.fp_status[FPST_AH]);
|
||||
|
|
|
|||
|
|
@ -207,6 +207,8 @@ typedef struct NVICState NVICState;
|
|||
* when FPCR.AH == 1 (bfloat16 conversions and multiplies,
|
||||
* and the reciprocal and square root estimate/step insns);
|
||||
* for half-precision
|
||||
* ZA: the "streaming sve" fp status.
|
||||
* ZA_F16: likewise for half-precision.
|
||||
*
|
||||
* Half-precision operations are governed by a separate
|
||||
* flush-to-zero control bit in FPSCR:FZ16. We pass a separate
|
||||
|
|
@ -227,6 +229,12 @@ typedef struct NVICState NVICState;
|
|||
* they ignore FPCR.RMode. But they don't ignore FPCR.FZ16,
|
||||
* which means we need an FPST_AH_F16 as well.
|
||||
*
|
||||
* The "ZA" float_status are for Streaming SVE operations which use
|
||||
* default-NaN and do not generate fp exceptions, which means that they
|
||||
* do not accumulate exception bits back into FPCR.
|
||||
* See e.g. FPAdd vs FPAdd_ZA pseudocode functions, and the setting
|
||||
* of fpcr.DN and fpexec parameters.
|
||||
*
|
||||
* To avoid having to transfer exception bits around, we simply
|
||||
* say that the FPSCR cumulative exception flags are the logical
|
||||
* OR of the flags in the four fp statuses. This relies on the
|
||||
|
|
@ -240,10 +248,12 @@ typedef enum ARMFPStatusFlavour {
|
|||
FPST_A64_F16,
|
||||
FPST_AH,
|
||||
FPST_AH_F16,
|
||||
FPST_ZA,
|
||||
FPST_ZA_F16,
|
||||
FPST_STD,
|
||||
FPST_STD_F16,
|
||||
} ARMFPStatusFlavour;
|
||||
#define FPST_COUNT 8
|
||||
#define FPST_COUNT 10
|
||||
|
||||
typedef struct CPUArchState {
|
||||
/* Regs for current mode. */
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ uint32_t vfp_get_fpsr_from_host(CPUARMState *env)
|
|||
a64_flags |= (get_float_exception_flags(&env->vfp.fp_status[FPST_A64_F16])
|
||||
& ~(float_flag_input_denormal_flushed | float_flag_input_denormal_used));
|
||||
/*
|
||||
* We do not merge in flags from FPST_AH or FPST_AH_F16, because
|
||||
* We do not merge in flags from FPST_{AH,ZA} or FPST_{AH,ZA}_F16, because
|
||||
* they are used for insns that must not set the cumulative exception bits.
|
||||
*/
|
||||
|
||||
|
|
@ -196,6 +196,8 @@ void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask)
|
|||
set_float_rounding_mode(i, &env->vfp.fp_status[FPST_A64]);
|
||||
set_float_rounding_mode(i, &env->vfp.fp_status[FPST_A32_F16]);
|
||||
set_float_rounding_mode(i, &env->vfp.fp_status[FPST_A64_F16]);
|
||||
set_float_rounding_mode(i, &env->vfp.fp_status[FPST_ZA]);
|
||||
set_float_rounding_mode(i, &env->vfp.fp_status[FPST_ZA_F16]);
|
||||
}
|
||||
if (changed & FPCR_FZ16) {
|
||||
bool ftz_enabled = val & FPCR_FZ16;
|
||||
|
|
@ -203,15 +205,18 @@ void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask)
|
|||
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_A64_F16]);
|
||||
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_STD_F16]);
|
||||
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_AH_F16]);
|
||||
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_ZA_F16]);
|
||||
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_A32_F16]);
|
||||
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_A64_F16]);
|
||||
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_STD_F16]);
|
||||
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_AH_F16]);
|
||||
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_ZA_F16]);
|
||||
}
|
||||
if (changed & FPCR_FZ) {
|
||||
bool ftz_enabled = val & FPCR_FZ;
|
||||
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_A32]);
|
||||
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_A64]);
|
||||
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_ZA]);
|
||||
/* FIZ is A64 only so FZ always makes A32 code flush inputs to zero */
|
||||
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status[FPST_A32]);
|
||||
}
|
||||
|
|
@ -223,6 +228,7 @@ void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask)
|
|||
bool fitz_enabled = (val & FPCR_FIZ) ||
|
||||
(val & (FPCR_FZ | FPCR_AH)) == FPCR_FZ;
|
||||
set_flush_inputs_to_zero(fitz_enabled, &env->vfp.fp_status[FPST_A64]);
|
||||
set_flush_inputs_to_zero(fitz_enabled, &env->vfp.fp_status[FPST_ZA]);
|
||||
}
|
||||
if (changed & FPCR_DN) {
|
||||
bool dnan_enabled = val & FPCR_DN;
|
||||
|
|
@ -240,9 +246,13 @@ void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask)
|
|||
/* Change behaviours for A64 FP operations */
|
||||
arm_set_ah_fp_behaviours(&env->vfp.fp_status[FPST_A64]);
|
||||
arm_set_ah_fp_behaviours(&env->vfp.fp_status[FPST_A64_F16]);
|
||||
arm_set_ah_fp_behaviours(&env->vfp.fp_status[FPST_ZA]);
|
||||
arm_set_ah_fp_behaviours(&env->vfp.fp_status[FPST_ZA_F16]);
|
||||
} else {
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_A64]);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_A64_F16]);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_ZA]);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status[FPST_ZA_F16]);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue