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;