aboutsummaryrefslogtreecommitdiff
path: root/target/riscv/translate.c
diff options
context:
space:
mode:
authorFrank Chang <frank.chang@sifive.com>2021-12-10 15:55:53 +0800
committerAlistair Francis <alistair.francis@wdc.com>2021-12-20 14:51:36 +1000
commit8e1ee1fb571cbfa7d6897560fed3cd9f367058a1 (patch)
tree6cf95ecbedd3a273a6c4a76e11bf8f41a86687bc /target/riscv/translate.c
parent7b07a37c2caad9252c6c5eec11ab9776826328ff (diff)
target/riscv: rvv-1.0: add translation-time vector context status
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> Signed-off-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20211210075704.23951-8-frank.chang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv/translate.c')
-rw-r--r--target/riscv/translate.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d445954dc7..8051090d2f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -62,7 +62,9 @@ typedef struct DisasContext {
uint32_t misa_ext;
uint32_t opcode;
uint32_t mstatus_fs;
+ uint32_t mstatus_vs;
uint32_t mstatus_hs_fs;
+ uint32_t mstatus_hs_vs;
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
@@ -348,6 +350,42 @@ static void mark_fs_dirty(DisasContext *ctx)
static inline void mark_fs_dirty(DisasContext *ctx) { }
#endif
+#ifndef CONFIG_USER_ONLY
+/* The states of mstatus_vs are:
+ * 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
+ * We will have already diagnosed disabled state,
+ * and need to turn initial/clean into dirty.
+ */
+static void mark_vs_dirty(DisasContext *ctx)
+{
+ TCGv tmp;
+
+ if (ctx->mstatus_vs != MSTATUS_VS) {
+ /* Remember the state change for the rest of the TB. */
+ ctx->mstatus_vs = MSTATUS_VS;
+
+ tmp = tcg_temp_new();
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
+ tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
+ tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
+ tcg_temp_free(tmp);
+ }
+
+ if (ctx->virt_enabled && ctx->mstatus_hs_vs != MSTATUS_VS) {
+ /* Remember the stage change for the rest of the TB. */
+ ctx->mstatus_hs_vs = MSTATUS_VS;
+
+ tmp = tcg_temp_new();
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
+ tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
+ tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
+ tcg_temp_free(tmp);
+ }
+}
+#else
+static inline void mark_vs_dirty(DisasContext *ctx) { }
+#endif
+
static void gen_set_rm(DisasContext *ctx, int rm)
{
if (ctx->frm == rm) {
@@ -631,6 +669,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->pc_succ_insn = ctx->base.pc_first;
ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
+ ctx->mstatus_vs = tb_flags & TB_FLAGS_MSTATUS_VS;
ctx->priv_ver = env->priv_ver;
#if !defined(CONFIG_USER_ONLY)
if (riscv_has_ext(env, RVH)) {
@@ -648,6 +687,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->ext_zfhmin = cpu->cfg.ext_zfhmin;
ctx->vlen = cpu->cfg.vlen;
ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS);
+ ctx->mstatus_hs_vs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_VS);
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);