@samitouri / QOSamiQemu / commits / b54ca6cbdc

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 <anjo@rev.ng> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Acked-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260520125406.28693-5-anjo@rev.ng> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Anton Johansson committed May 20, 2026 at 14:53 UTC b54ca6cbdce85511e08ae6d3cc770248120aaa2f
5 files changed +15 -11
target/riscv/cpu.h
+3 -3
@@ -232,7 +232,7 @@ struct CPUArchState {
232
233 /* Floating-Point state */
234 uint64_t fpr[32]; /* assume both F and D extensions */
235 - target_ulong frm;
235 + uint8_t frm;
236 float_status fp_status;
237
238 target_ulong badaddr;
@@ -667,8 +667,8 @@ G_NORETURN void riscv_raise_exception(CPURISCVState *env,
667 RISCVException exception,
668 uintptr_t pc);
669
670 -target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
671 -void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
670 +uint8_t riscv_cpu_get_fflags(CPURISCVState *env);
671 +void riscv_cpu_set_fflags(CPURISCVState *env, uint8_t);
672
673 #ifndef CONFIG_USER_ONLY
674 void cpu_set_exception_base(int vp_index, target_ulong address);
target/riscv/csr.c
+4
@@ -918,6 +918,10 @@ static RISCVException write_frm(CPURISCVState *env, int csrno,
918 static RISCVException read_fcsr(CPURISCVState *env, int csrno,
919 target_ulong *val)
920 {
921 + /*
922 + * This is an 8-bit operation, fflags make up the lower 5 bits and
923 + * frm the upper 3 bits of fcsr.
924 + */
925 *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
926 | (env->frm << FSR_RD_SHIFT);
927 return RISCV_EXCP_NONE;
target/riscv/fpu_helper.c
+5 -5
@@ -23,10 +23,10 @@
23 #include "fpu/softfloat.h"
24 #include "internals.h"
25
26 -target_ulong riscv_cpu_get_fflags(CPURISCVState *env)
26 +uint8_t riscv_cpu_get_fflags(CPURISCVState *env)
27 {
28 int soft = get_float_exception_flags(&env->fp_status);
29 - target_ulong hard = 0;
29 + uint8_t hard = 0;
30
31 hard |= (soft & float_flag_inexact) ? FPEXC_NX : 0;
32 hard |= (soft & float_flag_underflow) ? FPEXC_UF : 0;
@@ -37,7 +37,7 @@ target_ulong riscv_cpu_get_fflags(CPURISCVState *env)
37 return hard;
38 }
39
40 -void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong hard)
40 +void riscv_cpu_set_fflags(CPURISCVState *env, uint8_t hard)
41 {
42 int soft = 0;
43
@@ -52,7 +52,7 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong hard)
52
53 void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
54 {
55 - int softrm;
55 + FloatRoundMode softrm;
56
57 if (rm == RISCV_FRM_DYN) {
58 rm = env->frm;
@@ -82,7 +82,7 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
82
83 void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm)
84 {
85 - int softrm;
85 + FloatRoundMode softrm;
86
87 /* Always validate frm, even if rm != DYN. */
88 if (unlikely(env->frm >= 5)) {
target/riscv/machine.c
+1 -1
@@ -456,7 +456,7 @@ const VMStateDescription vmstate_riscv_cpu = {
456 VMSTATE_UINT64(env.pc, RISCVCPU),
457 VMSTATE_UINT64(env.load_res, RISCVCPU),
458 VMSTATE_UINT64(env.load_val, RISCVCPU),
459 - VMSTATE_UINTTL(env.frm, RISCVCPU),
459 + VMSTATE_UINT8(env.frm, RISCVCPU),
460 VMSTATE_UINTTL(env.badaddr, RISCVCPU),
461 VMSTATE_UINTTL(env.guest_phys_fault_addr, RISCVCPU),
462 VMSTATE_UINTTL(env.priv_ver, RISCVCPU),
target/riscv/translate.c
+2 -2
@@ -753,7 +753,7 @@ static void finalize_rvv_inst(DisasContext *ctx)
753 ctx->vstart_eq_zero = true;
754 }
755
756 -static void gen_set_rm(DisasContext *ctx, int rm)
756 +static void gen_set_rm(DisasContext *ctx, uint8_t rm)
757 {
758 if (ctx->frm == rm) {
759 return;
@@ -770,7 +770,7 @@ static void gen_set_rm(DisasContext *ctx, int rm)
770 gen_helper_set_rounding_mode(tcg_env, tcg_constant_i32(rm));
771 }
772
773 -static void gen_set_rm_chkfrm(DisasContext *ctx, int rm)
773 +static void gen_set_rm_chkfrm(DisasContext *ctx, uint8_t rm)
774 {
775 if (ctx->frm == rm && ctx->frm_valid) {
776 return;