diff options
Diffstat (limited to 'target/riscv/translate.c')
| -rw-r--r-- | target/riscv/translate.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 74b33fa3c9..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) { } @@ -337,6 +340,12 @@ EX_SH(12) } \ } while (0) +#define REQUIRE_32BIT(ctx) do { \ + if (!is_32bit(ctx)) { \ + return false; \ + } \ +} while (0) + #define REQUIRE_64BIT(ctx) do { \ if (is_32bit(ctx)) { \ return false; \ @@ -533,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); |