From: Anton Johansson Date: Wed, 20 May 2026 12:53:42 +0000 (+0200) Subject: target/riscv: Fix size of frm and fflags X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b54ca6cbdce85511e08ae6d3cc770248120aaa2f;p=thirdparty%2Fqemu.git target/riscv: Fix size of frm and fflags According to version 20250508 of the unprivileged specification the frm field of fcsr is 3-bits in size, fix it to 8-bits. Similarly fflags is 5 bits, fix to 8. Uses of frm is restricted to uint8_t where sensible, helpers still need 32-bit arguments and the DisasContext field is kept as int to represent -1 for an unknown rm. Signed-off-by: Anton Johansson Reviewed-by: Pierrick Bouvier Acked-by: Alistair Francis Message-ID: <20260520125406.28693-5-anjo@rev.ng> Signed-off-by: Alistair Francis --- diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 8f0e73b6b5..6692bff456 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -232,7 +232,7 @@ struct CPUArchState { /* Floating-Point state */ uint64_t fpr[32]; /* assume both F and D extensions */ - target_ulong frm; + uint8_t frm; float_status fp_status; target_ulong badaddr; @@ -667,8 +667,8 @@ G_NORETURN void riscv_raise_exception(CPURISCVState *env, RISCVException exception, uintptr_t pc); -target_ulong riscv_cpu_get_fflags(CPURISCVState *env); -void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong); +uint8_t riscv_cpu_get_fflags(CPURISCVState *env); +void riscv_cpu_set_fflags(CPURISCVState *env, uint8_t); #ifndef CONFIG_USER_ONLY void cpu_set_exception_base(int vp_index, target_ulong address); diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 2e81221b1d..8c2dcbeca4 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -918,6 +918,10 @@ static RISCVException write_frm(CPURISCVState *env, int csrno, static RISCVException read_fcsr(CPURISCVState *env, int csrno, target_ulong *val) { + /* + * This is an 8-bit operation, fflags make up the lower 5 bits and + * frm the upper 3 bits of fcsr. + */ *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT) | (env->frm << FSR_RD_SHIFT); return RISCV_EXCP_NONE; diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c index af40561b31..e6d1ffb1d6 100644 --- a/target/riscv/fpu_helper.c +++ b/target/riscv/fpu_helper.c @@ -23,10 +23,10 @@ #include "fpu/softfloat.h" #include "internals.h" -target_ulong riscv_cpu_get_fflags(CPURISCVState *env) +uint8_t riscv_cpu_get_fflags(CPURISCVState *env) { int soft = get_float_exception_flags(&env->fp_status); - target_ulong hard = 0; + uint8_t hard = 0; hard |= (soft & float_flag_inexact) ? FPEXC_NX : 0; hard |= (soft & float_flag_underflow) ? FPEXC_UF : 0; @@ -37,7 +37,7 @@ target_ulong riscv_cpu_get_fflags(CPURISCVState *env) return hard; } -void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong hard) +void riscv_cpu_set_fflags(CPURISCVState *env, uint8_t hard) { int soft = 0; @@ -52,7 +52,7 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong hard) void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm) { - int softrm; + FloatRoundMode softrm; if (rm == RISCV_FRM_DYN) { rm = env->frm; @@ -82,7 +82,7 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm) void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm) { - int softrm; + FloatRoundMode softrm; /* Always validate frm, even if rm != DYN. */ if (unlikely(env->frm >= 5)) { diff --git a/target/riscv/machine.c b/target/riscv/machine.c index a0376c7564..5c692e0fe6 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -456,7 +456,7 @@ const VMStateDescription vmstate_riscv_cpu = { VMSTATE_UINT64(env.pc, RISCVCPU), VMSTATE_UINT64(env.load_res, RISCVCPU), VMSTATE_UINT64(env.load_val, RISCVCPU), - VMSTATE_UINTTL(env.frm, RISCVCPU), + VMSTATE_UINT8(env.frm, RISCVCPU), VMSTATE_UINTTL(env.badaddr, RISCVCPU), VMSTATE_UINTTL(env.guest_phys_fault_addr, RISCVCPU), VMSTATE_UINTTL(env.priv_ver, RISCVCPU), diff --git a/target/riscv/translate.c b/target/riscv/translate.c index b444fde3ef..7c23996271 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -753,7 +753,7 @@ static void finalize_rvv_inst(DisasContext *ctx) ctx->vstart_eq_zero = true; } -static void gen_set_rm(DisasContext *ctx, int rm) +static void gen_set_rm(DisasContext *ctx, uint8_t rm) { if (ctx->frm == rm) { return; @@ -770,7 +770,7 @@ static void gen_set_rm(DisasContext *ctx, int rm) gen_helper_set_rounding_mode(tcg_env, tcg_constant_i32(rm)); } -static void gen_set_rm_chkfrm(DisasContext *ctx, int rm) +static void gen_set_rm_chkfrm(DisasContext *ctx, uint8_t rm) { if (ctx->frm == rm && ctx->frm_valid) { return;