@@ -22,6 +22,7 @@
#include "cpu.h"
#include "qemu/main-loop.h"
#include "exec/exec-all.h"
+#include "internals.h"
/* CSR function table */
static riscv_csr_operations csr_ops[];
@@ -174,6 +175,9 @@ static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
env->mstatus |= MSTATUS_FS;
#endif
env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
+ if (!riscv_cpu_set_rounding_mode(env, env->frm)) {
+ return -1;
+ }
return 0;
}
@@ -207,6 +211,9 @@ static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
env->vxsat = (val & FSR_VXSAT) >> FSR_VXSAT_SHIFT;
}
riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
+ if (!riscv_cpu_set_rounding_mode(env, env->frm)) {
+ return -1;
+ }
return 0;
}
@@ -50,13 +50,10 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong hard)
set_float_exception_flags(soft, &env->fp_status);
}
-void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
+bool riscv_cpu_set_rounding_mode(CPURISCVState *env, uint32_t rm)
{
int softrm;
- if (rm == 7) {
- rm = env->frm;
- }
switch (rm) {
case 0:
softrm = float_round_nearest_even;
@@ -74,10 +71,22 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
softrm = float_round_ties_away;
break;
default:
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+ return false;
}
set_float_rounding_mode(softrm, &env->fp_status);
+ return true;
+}
+
+void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
+{
+ if (rm == 7) {
+ rm = env->frm;
+ }
+
+ if (!riscv_cpu_set_rounding_mode(env, rm)) {
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+ }
}
uint64_t helper_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
@@ -27,4 +27,7 @@ FIELD(VDATA, VM, 8, 1)
FIELD(VDATA, LMUL, 9, 2)
FIELD(VDATA, NF, 11, 4)
FIELD(VDATA, WD, 11, 1)
+
+/* set float rounding mode */
+bool riscv_cpu_set_rounding_mode(CPURISCVState *env, uint32_t rm);
#endif
For scalar float instruction, round mode is encoded in instruction, so fp_status is updating dynamiclly. For vector float instruction, round mode is always frm, so update fp_status when frm changes is enough. Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> --- target/riscv/csr.c | 7 +++++++ target/riscv/fpu_helper.c | 19 ++++++++++++++----- target/riscv/internals.h | 3 +++ 3 files changed, 24 insertions(+), 5 deletions(-)