diff options
author | Frank Chang <frank.chang@sifive.com> | 2021-12-10 15:55:53 +0800 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2021-12-20 14:51:36 +1000 |
commit | 8e1ee1fb571cbfa7d6897560fed3cd9f367058a1 (patch) | |
tree | 6cf95ecbedd3a273a6c4a76e11bf8f41a86687bc /target/riscv/translate.c | |
parent | 7b07a37c2caad9252c6c5eec11ab9776826328ff (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.c | 40 |
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); |