From 2208cb46e60a825768b0d6aad1bd809f7b235bd1 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Jan 2025 16:27:26 +0000 Subject: target/arm: Define new fp_status_a32 and fp_status_a64 We want to split the existing fp_status in the Arm CPUState into separate float_status fields for AArch32 and AArch64. (This is because new control bits defined by FEAT_AFP only have an effect for AArch64, not AArch32.) To make this split we will: * define new fp_status_a32 and fp_status_a64 which have identical behaviour to the existing fp_status * move existing uses of fp_status to fp_status_a32 or fp_status_a64 as appropriate * delete the old fp_status when it has no uses left In this patch we add the new float_status fields. We will also need to split fp_status_f16, but we will do that as a separate series of patches. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20250124162836.2332150-7-peter.maydell@linaro.org --- target/arm/cpu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'target/arm/cpu.c') diff --git a/target/arm/cpu.c b/target/arm/cpu.c index dc0231233a..8bdd535db9 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -573,6 +573,8 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type) set_default_nan_mode(1, &env->vfp.standard_fp_status); set_default_nan_mode(1, &env->vfp.standard_fp_status_f16); arm_set_default_fp_behaviours(&env->vfp.fp_status); + arm_set_default_fp_behaviours(&env->vfp.fp_status_a32); + arm_set_default_fp_behaviours(&env->vfp.fp_status_a64); arm_set_default_fp_behaviours(&env->vfp.standard_fp_status); arm_set_default_fp_behaviours(&env->vfp.fp_status_f16); arm_set_default_fp_behaviours(&env->vfp.standard_fp_status_f16); -- cgit 1.4.1 From 2aa9656ebc26ea73c0cdb5c67409de1b9ef303c8 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Jan 2025 16:27:32 +0000 Subject: target/arm: Remove now-unused vfp.fp_status and FPST_FPCR Now we have moved all the uses of vfp.fp_status and FPST_FPCR to either the A32 or A64 fields, we can remove these. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20250124162836.2332150-13-peter.maydell@linaro.org --- target/arm/cpu.c | 1 - target/arm/cpu.h | 2 -- target/arm/tcg/translate.h | 6 ------ target/arm/vfp_helper.c | 8 +------- 4 files changed, 1 insertion(+), 16 deletions(-) (limited to 'target/arm/cpu.c') diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 8bdd535db9..a2b9bd3fb9 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -572,7 +572,6 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type) set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); set_default_nan_mode(1, &env->vfp.standard_fp_status); set_default_nan_mode(1, &env->vfp.standard_fp_status_f16); - arm_set_default_fp_behaviours(&env->vfp.fp_status); arm_set_default_fp_behaviours(&env->vfp.fp_status_a32); arm_set_default_fp_behaviours(&env->vfp.fp_status_a64); arm_set_default_fp_behaviours(&env->vfp.standard_fp_status); diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 337c538374..7b967bbd1d 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -633,7 +633,6 @@ typedef struct CPUArchState { /* There are a number of distinct float control structures: * - * fp_status: is the "normal" fp status. * fp_status_a32: is the "normal" fp status for AArch32 insns * fp_status_a64: is the "normal" fp status for AArch64 insns * fp_status_fp16: used for half-precision calculations @@ -660,7 +659,6 @@ typedef struct CPUArchState { * only thing which needs to read the exception flags being * an explicit FPSCR read. */ - float_status fp_status; float_status fp_status_a32; float_status fp_status_a64; float_status fp_status_f16; diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h index c8414d94d5..fca68b7c4c 100644 --- a/target/arm/tcg/translate.h +++ b/target/arm/tcg/translate.h @@ -670,7 +670,6 @@ static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb) * Enum for argument to fpstatus_ptr(). */ typedef enum ARMFPStatusFlavour { - FPST_FPCR, FPST_A32, FPST_A64, FPST_FPCR_F16, @@ -686,8 +685,6 @@ typedef enum ARMFPStatusFlavour { * been set up to point to the requested field in the CPU state struct. * The options are: * - * FPST_FPCR - * for non-FP16 operations controlled by the FPCR * FPST_A32 * for AArch32 non-FP16 operations controlled by the FPCR * FPST_A64 @@ -705,9 +702,6 @@ static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour) int offset; switch (flavour) { - case FPST_FPCR: - offset = offsetof(CPUARMState, vfp.fp_status); - break; case FPST_A32: offset = offsetof(CPUARMState, vfp.fp_status_a32); break; diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c index 034f26e5da..9fee6265f2 100644 --- a/target/arm/vfp_helper.c +++ b/target/arm/vfp_helper.c @@ -61,9 +61,8 @@ static inline uint32_t vfp_exceptbits_from_host(int host_bits) static uint32_t vfp_get_fpsr_from_host(CPUARMState *env) { - uint32_t i; + uint32_t i = 0; - i = get_float_exception_flags(&env->vfp.fp_status); i |= get_float_exception_flags(&env->vfp.fp_status_a32); i |= get_float_exception_flags(&env->vfp.fp_status_a64); i |= get_float_exception_flags(&env->vfp.standard_fp_status); @@ -82,7 +81,6 @@ static void vfp_clear_float_status_exc_flags(CPUARMState *env) * values. The caller should have arranged for env->vfp.fpsr to * be the architecturally up-to-date exception flag information first. */ - set_float_exception_flags(0, &env->vfp.fp_status); set_float_exception_flags(0, &env->vfp.fp_status_a32); set_float_exception_flags(0, &env->vfp.fp_status_a64); set_float_exception_flags(0, &env->vfp.fp_status_f16); @@ -112,7 +110,6 @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) i = float_round_to_zero; break; } - set_float_rounding_mode(i, &env->vfp.fp_status); set_float_rounding_mode(i, &env->vfp.fp_status_a32); set_float_rounding_mode(i, &env->vfp.fp_status_a64); set_float_rounding_mode(i, &env->vfp.fp_status_f16); @@ -126,8 +123,6 @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) } if (changed & FPCR_FZ) { bool ftz_enabled = val & FPCR_FZ; - set_flush_to_zero(ftz_enabled, &env->vfp.fp_status); - set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status); set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_a32); set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_a32); set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_a64); @@ -135,7 +130,6 @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) } if (changed & FPCR_DN) { bool dnan_enabled = val & FPCR_DN; - set_default_nan_mode(dnan_enabled, &env->vfp.fp_status); set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a32); set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a64); set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16); -- cgit 1.4.1 From 5f4ed6da85ff4abeb89bf9e6ad9481b82c5db0b0 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Jan 2025 16:27:33 +0000 Subject: target/arm: Define new fp_status_f16_a32 and fp_status_f16_a64 As the first part of splitting the existing fp_status_f16 into separate float_status fields for AArch32 and AArch64 (so that we can make FEAT_AFP control bits apply only for AArch64), define the two new fp_status_f16_a32 and fp_status_f16_a64 fields, but don't use them yet. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20250124162836.2332150-14-peter.maydell@linaro.org --- target/arm/cpu.c | 2 ++ target/arm/cpu.h | 4 ++++ target/arm/tcg/translate.h | 12 ++++++++++++ target/arm/vfp_helper.c | 14 ++++++++++++++ 4 files changed, 32 insertions(+) (limited to 'target/arm/cpu.c') diff --git a/target/arm/cpu.c b/target/arm/cpu.c index a2b9bd3fb9..ff8514edc6 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -576,6 +576,8 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type) arm_set_default_fp_behaviours(&env->vfp.fp_status_a64); arm_set_default_fp_behaviours(&env->vfp.standard_fp_status); arm_set_default_fp_behaviours(&env->vfp.fp_status_f16); + arm_set_default_fp_behaviours(&env->vfp.fp_status_f16_a32); + arm_set_default_fp_behaviours(&env->vfp.fp_status_f16_a64); arm_set_default_fp_behaviours(&env->vfp.standard_fp_status_f16); #ifndef CONFIG_USER_ONLY diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 7b967bbd1d..be409c5c76 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -636,6 +636,8 @@ typedef struct CPUArchState { * fp_status_a32: is the "normal" fp status for AArch32 insns * fp_status_a64: is the "normal" fp status for AArch64 insns * fp_status_fp16: used for half-precision calculations + * fp_status_fp16_a32: used for AArch32 half-precision calculations + * fp_status_fp16_a64: used for AArch64 half-precision calculations * standard_fp_status : the ARM "Standard FPSCR Value" * standard_fp_status_fp16 : used for half-precision * calculations with the ARM "Standard FPSCR Value" @@ -662,6 +664,8 @@ typedef struct CPUArchState { float_status fp_status_a32; float_status fp_status_a64; float_status fp_status_f16; + float_status fp_status_f16_a32; + float_status fp_status_f16_a64; float_status standard_fp_status; float_status standard_fp_status_f16; diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h index fca68b7c4c..d84c6d74aa 100644 --- a/target/arm/tcg/translate.h +++ b/target/arm/tcg/translate.h @@ -673,6 +673,8 @@ typedef enum ARMFPStatusFlavour { FPST_A32, FPST_A64, FPST_FPCR_F16, + FPST_A32_F16, + FPST_A64_F16, FPST_STD, FPST_STD_F16, } ARMFPStatusFlavour; @@ -691,6 +693,10 @@ typedef enum ARMFPStatusFlavour { * for AArch64 non-FP16 operations controlled by the FPCR * FPST_FPCR_F16 * for operations controlled by the FPCR where FPCR.FZ16 is to be used + * FPST_A32_F16 + * for AArch32 operations controlled by the FPCR where FPCR.FZ16 is to be used + * FPST_A64_F16 + * for AArch64 operations controlled by the FPCR where FPCR.FZ16 is to be used * FPST_STD * for A32/T32 Neon operations using the "standard FPSCR value" * FPST_STD_F16 @@ -711,6 +717,12 @@ static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour) case FPST_FPCR_F16: offset = offsetof(CPUARMState, vfp.fp_status_f16); break; + case FPST_A32_F16: + offset = offsetof(CPUARMState, vfp.fp_status_f16_a32); + break; + case FPST_A64_F16: + offset = offsetof(CPUARMState, vfp.fp_status_f16_a64); + break; case FPST_STD: offset = offsetof(CPUARMState, vfp.standard_fp_status); break; diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c index 9fee6265f2..45f9dfc886 100644 --- a/target/arm/vfp_helper.c +++ b/target/arm/vfp_helper.c @@ -69,6 +69,10 @@ static uint32_t vfp_get_fpsr_from_host(CPUARMState *env) /* FZ16 does not generate an input denormal exception. */ i |= (get_float_exception_flags(&env->vfp.fp_status_f16) & ~float_flag_input_denormal); + i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a32) + & ~float_flag_input_denormal); + i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a64) + & ~float_flag_input_denormal); i |= (get_float_exception_flags(&env->vfp.standard_fp_status_f16) & ~float_flag_input_denormal); return vfp_exceptbits_from_host(i); @@ -84,6 +88,8 @@ static void vfp_clear_float_status_exc_flags(CPUARMState *env) set_float_exception_flags(0, &env->vfp.fp_status_a32); set_float_exception_flags(0, &env->vfp.fp_status_a64); set_float_exception_flags(0, &env->vfp.fp_status_f16); + set_float_exception_flags(0, &env->vfp.fp_status_f16_a32); + set_float_exception_flags(0, &env->vfp.fp_status_f16_a64); set_float_exception_flags(0, &env->vfp.standard_fp_status); set_float_exception_flags(0, &env->vfp.standard_fp_status_f16); } @@ -113,12 +119,18 @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) set_float_rounding_mode(i, &env->vfp.fp_status_a32); set_float_rounding_mode(i, &env->vfp.fp_status_a64); set_float_rounding_mode(i, &env->vfp.fp_status_f16); + set_float_rounding_mode(i, &env->vfp.fp_status_f16_a32); + set_float_rounding_mode(i, &env->vfp.fp_status_f16_a64); } if (changed & FPCR_FZ16) { bool ftz_enabled = val & FPCR_FZ16; set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16); + set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a32); + set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a64); set_flush_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16); set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16); + set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a32); + set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a64); set_flush_inputs_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16); } if (changed & FPCR_FZ) { @@ -133,6 +145,8 @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a32); set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a64); set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16); + set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a32); + set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a64); } } -- cgit 1.4.1 From 3847b5b1fbb2d6d4ab1dffd8842ffc3d0c3ddb37 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Jan 2025 16:27:38 +0000 Subject: target/arm: Remove now-unused vfp.fp_status_f16 and FPST_FPCR_F16 Now we have moved all the uses of vfp.fp_status_f16 and FPST_FPCR_F16 to the new A32 or A64 fields, we can remove these. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20250124162836.2332150-19-peter.maydell@linaro.org --- target/arm/cpu.c | 1 - target/arm/cpu.h | 2 -- target/arm/tcg/translate.h | 6 ------ target/arm/vfp_helper.c | 7 ------- 4 files changed, 16 deletions(-) (limited to 'target/arm/cpu.c') diff --git a/target/arm/cpu.c b/target/arm/cpu.c index ff8514edc6..7a83b9ee34 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -575,7 +575,6 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type) arm_set_default_fp_behaviours(&env->vfp.fp_status_a32); arm_set_default_fp_behaviours(&env->vfp.fp_status_a64); arm_set_default_fp_behaviours(&env->vfp.standard_fp_status); - arm_set_default_fp_behaviours(&env->vfp.fp_status_f16); arm_set_default_fp_behaviours(&env->vfp.fp_status_f16_a32); arm_set_default_fp_behaviours(&env->vfp.fp_status_f16_a64); arm_set_default_fp_behaviours(&env->vfp.standard_fp_status_f16); diff --git a/target/arm/cpu.h b/target/arm/cpu.h index be409c5c76..2213c27734 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -635,7 +635,6 @@ typedef struct CPUArchState { * * fp_status_a32: is the "normal" fp status for AArch32 insns * fp_status_a64: is the "normal" fp status for AArch64 insns - * fp_status_fp16: used for half-precision calculations * fp_status_fp16_a32: used for AArch32 half-precision calculations * fp_status_fp16_a64: used for AArch64 half-precision calculations * standard_fp_status : the ARM "Standard FPSCR Value" @@ -663,7 +662,6 @@ typedef struct CPUArchState { */ float_status fp_status_a32; float_status fp_status_a64; - float_status fp_status_f16; float_status fp_status_f16_a32; float_status fp_status_f16_a64; float_status standard_fp_status; diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h index d84c6d74aa..084ee63d99 100644 --- a/target/arm/tcg/translate.h +++ b/target/arm/tcg/translate.h @@ -672,7 +672,6 @@ static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb) typedef enum ARMFPStatusFlavour { FPST_A32, FPST_A64, - FPST_FPCR_F16, FPST_A32_F16, FPST_A64_F16, FPST_STD, @@ -691,8 +690,6 @@ typedef enum ARMFPStatusFlavour { * for AArch32 non-FP16 operations controlled by the FPCR * FPST_A64 * for AArch64 non-FP16 operations controlled by the FPCR - * FPST_FPCR_F16 - * for operations controlled by the FPCR where FPCR.FZ16 is to be used * FPST_A32_F16 * for AArch32 operations controlled by the FPCR where FPCR.FZ16 is to be used * FPST_A64_F16 @@ -714,9 +711,6 @@ static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour) case FPST_A64: offset = offsetof(CPUARMState, vfp.fp_status_a64); break; - case FPST_FPCR_F16: - offset = offsetof(CPUARMState, vfp.fp_status_f16); - break; case FPST_A32_F16: offset = offsetof(CPUARMState, vfp.fp_status_f16_a32); break; diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c index f3aa80bbfb..3ed69d7369 100644 --- a/target/arm/vfp_helper.c +++ b/target/arm/vfp_helper.c @@ -67,8 +67,6 @@ static uint32_t vfp_get_fpsr_from_host(CPUARMState *env) i |= get_float_exception_flags(&env->vfp.fp_status_a64); i |= get_float_exception_flags(&env->vfp.standard_fp_status); /* FZ16 does not generate an input denormal exception. */ - i |= (get_float_exception_flags(&env->vfp.fp_status_f16) - & ~float_flag_input_denormal); i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a32) & ~float_flag_input_denormal); i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a64) @@ -87,7 +85,6 @@ static void vfp_clear_float_status_exc_flags(CPUARMState *env) */ set_float_exception_flags(0, &env->vfp.fp_status_a32); set_float_exception_flags(0, &env->vfp.fp_status_a64); - set_float_exception_flags(0, &env->vfp.fp_status_f16); set_float_exception_flags(0, &env->vfp.fp_status_f16_a32); set_float_exception_flags(0, &env->vfp.fp_status_f16_a64); set_float_exception_flags(0, &env->vfp.standard_fp_status); @@ -118,17 +115,14 @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) } set_float_rounding_mode(i, &env->vfp.fp_status_a32); set_float_rounding_mode(i, &env->vfp.fp_status_a64); - set_float_rounding_mode(i, &env->vfp.fp_status_f16); set_float_rounding_mode(i, &env->vfp.fp_status_f16_a32); set_float_rounding_mode(i, &env->vfp.fp_status_f16_a64); } if (changed & FPCR_FZ16) { bool ftz_enabled = val & FPCR_FZ16; - set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16); set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a32); set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a64); set_flush_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16); - set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16); set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a32); set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a64); set_flush_inputs_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16); @@ -144,7 +138,6 @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) bool dnan_enabled = val & FPCR_DN; set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a32); set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a64); - set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16); set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a32); set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a64); } -- cgit 1.4.1