From: Anatoly Parshintsev <kupokupokup...@gmail.com> Signed-off-by: Anatoly Parshintsev <kupokupokup...@gmail.com> --- target/riscv/translate.c | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 79dca2291b..338a967e0c 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -63,6 +63,10 @@ typedef struct DisasContext { uint16_t vlen; uint16_t mlen; bool vl_eq_vlmax; + /* PointerMasking extension */ + uint8_t pm_enabled; + target_ulong pm_mask; + target_ulong pm_base; } DisasContext; #ifdef TARGET_RISCV64 @@ -90,6 +94,38 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext) return ctx->misa & ext; } +/* Generates address adjustment for PointerMasking */ +static void gen_pm_adjust_address(DisasContext *s, + TCGv_i64 dst, + TCGv_i64 src) +{ + if (s->pm_enabled == 0) { + /* Load unmodified address */ + tcg_gen_mov_i64(dst, src); + } else { + TCGv_i64 mask_neg = tcg_const_i64(~s->pm_mask); + TCGv_i64 base = tcg_const_i64(s->pm_base); + /* calculate (addr & ~mask) */ + TCGv res1 = tcg_temp_new(); + tcg_gen_and_tl(res1, mask_neg, src); + /* calculate (1) | (base) */ + TCGv res2 = tcg_temp_new(); + tcg_gen_or_tl(res2, res1, base); + /* move result to dst */ + tcg_gen_mov_i64(dst, res2); + /* free allocated temps */ + tcg_temp_free(res1); + tcg_temp_free(res2); + tcg_temp_free_i64(mask_neg); + tcg_temp_free_i64(base); + } +} + +static TCGv_i64 apply_pointer_masking(DisasContext *s, TCGv_i64 addr) +{ + gen_pm_adjust_address(s, addr, addr); + return addr; +} /* * RISC-V requires NaN-boxing of narrower width floating point values. * This applies when a 32-bit value is assigned to a 64-bit FP register. @@ -800,8 +836,36 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) } else { ctx->virt_enabled = false; } + if (riscv_has_ext(env, RVJ)) { + switch (env->priv) { + case PRV_U: + ctx->pm_enabled = get_field(env->mmte, UMTE_U_PM_ENABLE); + ctx->pm_mask = env->upmmask; + ctx->pm_base = env->upmbase; + break; + case PRV_S: + ctx->pm_enabled = get_field(env->mmte, SMTE_S_PM_ENABLE); + ctx->pm_mask = env->spmmask; + ctx->pm_base = env->spmbase; + break; + case PRV_M: + ctx->pm_enabled = get_field(env->mmte, MMTE_M_PM_ENABLE); + ctx->pm_mask = env->mpmmask; + ctx->pm_base = env->mpmbase; + break; + default: + assert(0 && "Unreachable"); + } + } else { + ctx->pm_enabled = 0; + ctx->pm_mask = 0; + ctx->pm_base = 0; + } #else ctx->virt_enabled = false; + ctx->pm_enabled = 0; + ctx->pm_mask = 0; + ctx->pm_base = 0; #endif ctx->misa = env->misa; ctx->frm = -1; /* unknown rounding mode */ @@ -932,3 +996,4 @@ void riscv_translate_init(void) load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val), "load_val"); } + -- 2.20.1