diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 99160d01..5b63e012 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -3285,6 +3285,7 @@ #define cpu_reg cpu_reg_aarch64 #define cpu_reg_sp cpu_reg_sp_aarch64 #define disas_sve disas_sve_aarch64 +#define fp_exception_el fp_exception_el_aarch64 #define gen_a64_set_pc_im gen_a64_set_pc_im_aarch64 #define helper_advsimd_acge_f16 helper_advsimd_acge_f16_aarch64 #define helper_advsimd_acgt_f16 helper_advsimd_acgt_f16_aarch64 @@ -4150,6 +4151,8 @@ #define read_cpu_reg read_cpu_reg_aarch64 #define read_cpu_reg_sp read_cpu_reg_sp_aarch64 #define sve_access_check sve_access_check_aarch64 +#define sve_exception_el sve_exception_el_aarch64 +#define sve_zcr_len_for_el sve_zcr_len_for_el_aarch64 #define unallocated_encoding unallocated_encoding_aarch64 #define vfp_expand_imm vfp_expand_imm_aarch64 #define write_fp_dreg write_fp_dreg_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 37eb669c..77d2722e 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -3285,6 +3285,7 @@ #define cpu_reg cpu_reg_aarch64eb #define cpu_reg_sp cpu_reg_sp_aarch64eb #define disas_sve disas_sve_aarch64eb +#define fp_exception_el fp_exception_el_aarch64eb #define gen_a64_set_pc_im gen_a64_set_pc_im_aarch64eb #define helper_advsimd_acge_f16 helper_advsimd_acge_f16_aarch64eb #define helper_advsimd_acgt_f16 helper_advsimd_acgt_f16_aarch64eb @@ -4150,6 +4151,8 @@ #define read_cpu_reg read_cpu_reg_aarch64eb #define read_cpu_reg_sp read_cpu_reg_sp_aarch64eb #define sve_access_check sve_access_check_aarch64eb +#define sve_exception_el sve_exception_el_aarch64eb +#define sve_zcr_len_for_el sve_zcr_len_for_el_aarch64eb #define unallocated_encoding unallocated_encoding_aarch64eb #define vfp_expand_imm vfp_expand_imm_aarch64eb #define write_fp_dreg write_fp_dreg_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index c60de56d..424ace34 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -3274,4 +3274,7 @@ #define arm_reset_cpu arm_reset_cpu_arm #define arm_set_cpu_off arm_set_cpu_off_arm #define arm_set_cpu_on arm_set_cpu_on_arm +#define fp_exception_el fp_exception_el_arm +#define sve_exception_el sve_exception_el_arm +#define sve_zcr_len_for_el sve_zcr_len_for_el_arm #endif diff --git a/qemu/armeb.h b/qemu/armeb.h index 209bb8db..fa0d42f8 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -3274,4 +3274,7 @@ #define arm_reset_cpu arm_reset_cpu_armeb #define arm_set_cpu_off arm_set_cpu_off_armeb #define arm_set_cpu_on arm_set_cpu_on_armeb +#define fp_exception_el fp_exception_el_armeb +#define sve_exception_el sve_exception_el_armeb +#define sve_zcr_len_for_el sve_zcr_len_for_el_armeb #endif diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 39ae9e6b..dada2713 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -3283,6 +3283,9 @@ arm_symbols = ( 'arm_reset_cpu', 'arm_set_cpu_off', 'arm_set_cpu_on', + 'fp_exception_el', + 'sve_exception_el', + 'sve_zcr_len_for_el', ) aarch64_symbols = ( @@ -3306,6 +3309,7 @@ aarch64_symbols = ( 'cpu_reg', 'cpu_reg_sp', 'disas_sve', + 'fp_exception_el', 'gen_a64_set_pc_im', 'helper_advsimd_acge_f16', 'helper_advsimd_acgt_f16', @@ -4171,6 +4175,8 @@ aarch64_symbols = ( 'read_cpu_reg', 'read_cpu_reg_sp', 'sve_access_check', + 'sve_exception_el', + 'sve_zcr_len_for_el', 'unallocated_encoding', 'vfp_expand_imm', 'write_fp_dreg', diff --git a/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index c86b9b24..05bbc5dc 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -864,6 +864,10 @@ target_ulong do_arm_semihosting(CPUARMState *env); void aarch64_sync_32_to_64(CPUARMState *env); void aarch64_sync_64_to_32(CPUARMState *env); +int fp_exception_el(CPUARMState *env, int cur_el); +int sve_exception_el(CPUARMState *env, int cur_el); +uint32_t sve_zcr_len_for_el(CPUARMState *env, int el); + static inline bool is_a64(CPUARMState *env) { return env->aarch64; diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index 87e8ab2e..7c716b3d 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -3831,7 +3831,7 @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = { * take care of raising that exception. * C.f. the ARM pseudocode function CheckSVEEnabled. */ -static int sve_exception_el(CPUARMState *env, int el) +int sve_exception_el(CPUARMState *env, int el) { #ifndef CONFIG_USER_ONLY if (el <= 1) { @@ -3889,7 +3889,7 @@ static int sve_exception_el(CPUARMState *env, int el) /* * Given that SVE is enabled, return the vector length for EL. */ -static uint32_t sve_zcr_len_for_el(CPUARMState *env, int el) +uint32_t sve_zcr_len_for_el(CPUARMState *env, int el) { ARMCPU *cpu = arm_env_get_cpu(env); uint32_t zcr_len = cpu->sve_max_vq - 1; @@ -11776,7 +11776,7 @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes) /* Return the exception level to which FP-disabled exceptions should * be taken, or 0 if FP is enabled. */ -static int fp_exception_el(CPUARMState *env, int cur_el) +int fp_exception_el(CPUARMState *env, int cur_el) { #ifndef CONFIG_USER_ONLY int fpen; diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 6fb9cfc4..ca4d7031 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -182,11 +182,15 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f, cpu_fprintf(f, "\n"); return; } + if (fp_exception_el(env, el) != 0) { + cpu_fprintf(f, " FPU disabled\n"); + return; + } cpu_fprintf(f, " FPCR=%08x FPSR=%08x\n", vfp_get_fpcr(env), vfp_get_fpsr(env)); - if (arm_feature(env, ARM_FEATURE_SVE)) { - int j, zcr_len = env->vfp.zcr_el[1] & 0xf; /* fix for system mode */ + if (arm_feature(env, ARM_FEATURE_SVE) && sve_exception_el(env, el) == 0) { + int j, zcr_len = sve_zcr_len_for_el(env, el); for (i = 0; i <= FFR_PRED_NUM; i++) { bool eol;