qemu-devel
[Top][All Lists]
Advanced

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

Re: [PATCH v7 3/4] target/riscv: smstateen check for fcsr


From: Weiwei Li
Subject: Re: [PATCH v7 3/4] target/riscv: smstateen check for fcsr
Date: Wed, 3 Aug 2022 16:32:18 +0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.14.0


在 2022/8/2 上午1:18, Mayuresh Chitale 写道:
If smstateen is implemented and sstateen0.fcsr is clear then the
floating point operations must return illegal instruction exception.

I think this is not correct. The exception for float point operations must be illegal instruction exception

if FCSR is not existed(that is misa.F is zero and Zfinx is not supported). However, when FCSR is exsited,

the final exception should be decided by current privilege level and the stateen related csr values just

like the access control of FCSR.

Regards,

Weiwei Li


Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
---
  target/riscv/csr.c                        | 23 +++++++++++++
  target/riscv/insn_trans/trans_rvf.c.inc   | 40 +++++++++++++++++++++--
  target/riscv/insn_trans/trans_rvzfh.c.inc | 12 +++++++
  3 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 011d6c5976..0512391220 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -79,6 +79,10 @@ static RISCVException fs(CPURISCVState *env, int csrno)
          !RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
          return RISCV_EXCP_ILLEGAL_INST;
      }
+
+    if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
+        return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR);
+    }
  #endif
      return RISCV_EXCP_NONE;
  }
@@ -1866,6 +1870,9 @@ static RISCVException write_mstateen0(CPURISCVState *env, 
int csrno,
                                        target_ulong new_val)
  {
      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+    if (!riscv_has_ext(env, RVF)) {
+        wr_mask |= SMSTATEEN0_FCSR;
+    }
return write_mstateen(env, csrno, wr_mask, new_val);
  }
@@ -1914,6 +1921,10 @@ static RISCVException write_mstateen0h(CPURISCVState 
*env, int csrno,
  {
      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+ if (!riscv_has_ext(env, RVF)) {
+        wr_mask |= SMSTATEEN0_FCSR;
+    }
+
      return write_mstateenh(env, csrno, wr_mask, new_val);
  }
@@ -1963,6 +1974,10 @@ static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
  {
      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+ if (!riscv_has_ext(env, RVF)) {
+        wr_mask |= SMSTATEEN0_FCSR;
+    }
+
      return write_hstateen(env, csrno, wr_mask, new_val);
  }
@@ -2014,6 +2029,10 @@ static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
  {
      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+ if (!riscv_has_ext(env, RVF)) {
+        wr_mask |= SMSTATEEN0_FCSR;
+    }
+
      return write_hstateenh(env, csrno, wr_mask, new_val);
  }
@@ -2073,6 +2092,10 @@ static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
  {
      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+ if (!riscv_has_ext(env, RVF)) {
+        wr_mask |= SMSTATEEN0_FCSR;
+    }
+
      return write_sstateen(env, csrno, wr_mask, new_val);
  }
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index a1d3eb52ad..ce8a0cc34b 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -24,9 +24,43 @@
              return false; \
  } while (0)
-#define REQUIRE_ZFINX_OR_F(ctx) do {\
-    if (!ctx->cfg_ptr->ext_zfinx) { \
-        REQUIRE_EXT(ctx, RVF); \
+#ifndef CONFIG_USER_ONLY
+static inline bool smstateen_check(DisasContext *ctx, int index)
+{
+    CPUState *cpu = ctx->cs;
+    CPURISCVState *env = cpu->env_ptr;
+    uint64_t stateen = env->mstateen[index];
+
+    if (!ctx->cfg_ptr->ext_smstateen || env->priv == PRV_M) {
+        return true;
+    }
+
+    if (ctx->virt_enabled) {
+        stateen &= env->hstateen[index];
+    }
+
+    if (env->priv == PRV_U && has_ext(ctx, RVS)) {
+        stateen &= env->sstateen[index];
+    }
+
+    if (!(stateen & SMSTATEEN0_FCSR)) {
+        return false;
+    }
+
+    return true;
+}
+#else
+#define smstateen_check(ctx, index) (true)
+#endif
+
+#define REQUIRE_ZFINX_OR_F(ctx) do { \
+    if (!has_ext(ctx, RVF)) { \
+        if (!ctx->cfg_ptr->ext_zfinx) { \
+            return false; \
+        } \
+        if (!smstateen_check(ctx, 0)) { \
+            return false; \
+        } \
      } \
  } while (0)
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc
index 5d07150cd0..44d962c920 100644
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
@@ -20,18 +20,27 @@
      if (!ctx->cfg_ptr->ext_zfh) {      \
          return false;         \
      }                         \
+    if (!smstateen_check(ctx, 0)) { \
+        return false; \
+    } \
  } while (0)
#define REQUIRE_ZHINX_OR_ZFH(ctx) do { \
      if (!ctx->cfg_ptr->ext_zhinx && !ctx->cfg_ptr->ext_zfh) { \
          return false;                  \
      }                                  \
+    if (!smstateen_check(ctx, 0)) { \
+        return false; \
+    } \
  } while (0)
#define REQUIRE_ZFH_OR_ZFHMIN(ctx) do { \
      if (!(ctx->cfg_ptr->ext_zfh || ctx->cfg_ptr->ext_zfhmin)) { \
          return false;                         \
      }                                         \
+    if (!smstateen_check(ctx, 0)) { \
+        return false; \
+    } \
  } while (0)
#define REQUIRE_ZFH_OR_ZFHMIN_OR_ZHINX_OR_ZHINXMIN(ctx) do { \
@@ -39,6 +48,9 @@
            ctx->cfg_ptr->ext_zhinx || ctx->cfg_ptr->ext_zhinxmin)) {     \
          return false;                                        \
      }                                                        \
+    if (!smstateen_check(ctx, 0)) { \
+        return false; \
+    } \
  } while (0)
static bool trans_flh(DisasContext *ctx, arg_flh *a)




reply via email to

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