summaryrefslogtreecommitdiff
path: root/target/riscv/csr.c
diff options
context:
space:
mode:
authorAlistair Francis <alistair.francis@wdc.com>2019-07-30 16:35:24 -0700
committerPalmer Dabbelt <palmer@sifive.com>2019-09-17 08:42:42 -0700
commitb345b48078d79ebe154a50f75e66999605abcc70 (patch)
tree4604c04876cfd3a404a43e6028ad04751dbb7a97 /target/riscv/csr.c
parentf14d65e8992499a179ecdf1901137ce496a0a607 (diff)
downloadqemu-b345b48078d79ebe154a50f75e66999605abcc70.zip
target/riscv: Create function to test if FP is enabled
Let's create a function that tests if floating point support is enabled. We can then protect all floating point operations based on if they are enabled. This patch so far doesn't change anything, it's just preparing for the Hypervisor support for floating point operations. Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Christophe de Dinechin <dinechin@redhat.com> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
Diffstat (limited to 'target/riscv/csr.c')
-rw-r--r--target/riscv/csr.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e0d4586760..2789215b5e 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -46,7 +46,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
static int fs(CPURISCVState *env, int csrno)
{
#if !defined(CONFIG_USER_ONLY)
- if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
+ if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
return -1;
}
#endif
@@ -108,7 +108,7 @@ static int pmp(CPURISCVState *env, int csrno)
static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
- if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
+ if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
return -1;
}
#endif
@@ -119,7 +119,7 @@ static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
- if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
+ if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
return -1;
}
env->mstatus |= MSTATUS_FS;
@@ -131,7 +131,7 @@ static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
- if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
+ if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
return -1;
}
#endif
@@ -142,7 +142,7 @@ static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
- if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
+ if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
return -1;
}
env->mstatus |= MSTATUS_FS;
@@ -154,7 +154,7 @@ static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
- if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
+ if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
return -1;
}
#endif
@@ -166,7 +166,7 @@ static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
- if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
+ if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
return -1;
}
env->mstatus |= MSTATUS_FS;
@@ -307,6 +307,7 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
{
target_ulong mstatus = env->mstatus;
target_ulong mask = 0;
+ int dirty;
/* flush tlb on mstatus fields that affect VM */
if (env->priv_ver <= PRIV_VERSION_1_09_1) {
@@ -340,8 +341,9 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
mstatus = (mstatus & ~mask) | (val & mask);
- int dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
- ((mstatus & MSTATUS_XS) == MSTATUS_XS);
+ dirty = (riscv_cpu_fp_enabled(env) &&
+ ((mstatus & MSTATUS_FS) == MSTATUS_FS)) |
+ ((mstatus & MSTATUS_XS) == MSTATUS_XS);
mstatus = set_field(mstatus, MSTATUS_SD, dirty);
env->mstatus = mstatus;