qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v8 30/62] target/riscv: Update fp_status when float rounding


From: Alistair Francis
Subject: Re: [PATCH v8 30/62] target/riscv: Update fp_status when float rounding mode changes
Date: Fri, 29 May 2020 12:59:16 -0700

On Thu, May 21, 2020 at 3:45 AM LIU Zhiwei <zhiwei_liu@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_liu@c-sky.com>

Reviewed-by: Alistair Francis <alistair.francis@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
>
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]