[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 17/26] target/riscv: Set mstatus_hs.[SD|FS] bits if Clean and V=1
From: |
Alistair Francis |
Subject: |
[PULL 17/26] target/riscv: Set mstatus_hs.[SD|FS] bits if Clean and V=1 in mark_fs_dirty() |
Date: |
Thu, 7 Oct 2021 16:47:42 +1000 |
From: Frank Chang <frank.chang@sifive.com>
When V=1, both vsstauts.FS and HS-level sstatus.FS are in effect.
Modifying the floating-point state when V=1 causes both fields to
be set to 3 (Dirty).
However, it's possible that HS-level sstatus.FS is Clean and VS-level
vsstatus.FS is Dirty at the time mark_fs_dirty() is called when V=1.
We can't early return for this case because we still need to set
sstatus.FS to Dirty according to spec.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Vincent Chen <vincent.chen@sifive.com>
Tested-by: Vincent Chen <vincent.chen@sifive.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20210921020234.123448-1-frank.chang@sifive.com
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 4 ++++
target/riscv/translate.c | 30 +++++++++++++++++-------------
2 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index bd519c9090..9e55b2f5b1 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -393,6 +393,7 @@ FIELD(TB_FLAGS, SEW, 5, 3)
FIELD(TB_FLAGS, VILL, 8, 1)
/* Is a Hypervisor instruction load/store allowed? */
FIELD(TB_FLAGS, HLSX, 9, 1)
+FIELD(TB_FLAGS, MSTATUS_HS_FS, 10, 2)
bool riscv_cpu_is_32bit(CPURISCVState *env);
@@ -449,6 +450,9 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env,
target_ulong *pc,
get_field(env->hstatus, HSTATUS_HU))) {
flags = FIELD_DP32(flags, TB_FLAGS, HLSX, 1);
}
+
+ flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS,
+ get_field(env->mstatus_hs, MSTATUS_FS));
}
#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b2d3444bc5..d2442f0cf5 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -58,6 +58,7 @@ typedef struct DisasContext {
target_ulong misa;
uint32_t opcode;
uint32_t mstatus_fs;
+ uint32_t mstatus_hs_fs;
uint32_t mem_idx;
/* Remember the rounding mode encoded in the previous fp instruction,
which we have already installed into env->fp_status. Or -1 for
@@ -280,27 +281,29 @@ static void gen_jal(DisasContext *ctx, int rd,
target_ulong imm)
static void mark_fs_dirty(DisasContext *ctx)
{
TCGv tmp;
- target_ulong sd;
+ target_ulong sd = is_32bit(ctx) ? MSTATUS32_SD : MSTATUS64_SD;
- if (ctx->mstatus_fs == MSTATUS_FS) {
- return;
- }
- /* Remember the state change for the rest of the TB. */
- ctx->mstatus_fs = MSTATUS_FS;
+ if (ctx->mstatus_fs != MSTATUS_FS) {
+ /* Remember the state change for the rest of the TB. */
+ ctx->mstatus_fs = MSTATUS_FS;
- tmp = tcg_temp_new();
- sd = is_32bit(ctx) ? MSTATUS32_SD : MSTATUS64_SD;
+ tmp = tcg_temp_new();
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
+ tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | sd);
+ tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
+ tcg_temp_free(tmp);
+ }
- tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
- tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | sd);
- tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
+ if (ctx->virt_enabled && ctx->mstatus_hs_fs != MSTATUS_FS) {
+ /* Remember the stage change for the rest of the TB. */
+ ctx->mstatus_hs_fs = MSTATUS_FS;
- if (ctx->virt_enabled) {
+ tmp = tcg_temp_new();
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | sd);
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
+ tcg_temp_free(tmp);
}
- tcg_temp_free(tmp);
}
#else
static inline void mark_fs_dirty(DisasContext *ctx) { }
@@ -539,6 +542,7 @@ static void riscv_tr_init_disas_context(DisasContextBase
*dcbase, CPUState *cs)
ctx->frm = -1; /* unknown rounding mode */
ctx->ext_ifencei = cpu->cfg.ext_ifencei;
ctx->vlen = cpu->cfg.vlen;
+ ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS);
ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX);
ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL);
ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
--
2.31.1
[PULL 12/26] target/riscv: Add a REQUIRE_32BIT macro, Alistair Francis, 2021/10/07
[PULL 13/26] target/riscv: Add rev8 instruction, removing grev/grevi, Alistair Francis, 2021/10/07
[PULL 14/26] target/riscv: Add zext.h instructions to Zbb, removing pack/packu/packh, Alistair Francis, 2021/10/07
[PULL 15/26] target/riscv: Remove RVB (replaced by Zb[abcs]), Alistair Francis, 2021/10/07
[PULL 16/26] disas/riscv: Add Zb[abcs] instructions, Alistair Francis, 2021/10/07
[PULL 17/26] target/riscv: Set mstatus_hs.[SD|FS] bits if Clean and V=1 in mark_fs_dirty(),
Alistair Francis <=
[PULL 18/26] hw/char: ibex_uart: Register device in 'input' category, Alistair Francis, 2021/10/07
[PULL 19/26] hw/char: shakti_uart: Register device in 'input' category, Alistair Francis, 2021/10/07
[PULL 20/26] hw/char: sifive_uart: Register device in 'input' category, Alistair Francis, 2021/10/07
[PULL 21/26] hw/char/mchp_pfsoc_mmuart: Simplify MCHP_PFSOC_MMUART_REG definition, Alistair Francis, 2021/10/07
[PULL 24/26] hw/dma: sifive_pdma: Fix Control.claim bit detection, Alistair Francis, 2021/10/07
[PULL 25/26] hw/dma: sifive_pdma: Don't run DMA when channel is disclaimed, Alistair Francis, 2021/10/07
[PULL 22/26] hw/char/mchp_pfsoc_mmuart: Use a MemoryRegion container, Alistair Francis, 2021/10/07
[PULL 23/26] hw/char/mchp_pfsoc_mmuart: QOM'ify PolarFire MMUART, Alistair Francis, 2021/10/07
[PULL 26/26] hw/riscv: shakti_c: Mark as not user creatable, Alistair Francis, 2021/10/07
Re: [PULL 00/26] riscv-to-apply queue, Richard Henderson, 2021/10/07