On Thu, May 21, 2020 at 3:45 AM LIU Zhiwei <zhiwei_...@c-sky.com> wrote: > > 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_...@c-sky.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > target/riscv/csr.c | 7 +++++++ > target/riscv/fpu_helper.c | 19 ++++++++++++++----- > target/riscv/internals.h | 3 +++ > 3 files changed, 24 insertions(+), 5 deletions(-) > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index d71c49dfff..438093152b 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -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; > } > > diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c > index 0b79562a69..262610e837 100644 > --- a/target/riscv/fpu_helper.c > +++ b/target/riscv/fpu_helper.c > @@ -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, > diff --git a/target/riscv/internals.h b/target/riscv/internals.h > index f699d80c41..52f6af2513 100644 > --- a/target/riscv/internals.h > +++ b/target/riscv/internals.h > @@ -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 > -- > 2.23.0 > >