From 028d27ae4c1240e912b352c258f6e7e2c7fc5508 Mon Sep 17 00:00:00 2001 From: Denis Drakhnya Date: Thu, 26 Nov 2020 22:02:34 +0200 Subject: [PATCH] target: e2k: Add setwd helper. --- target/e2k/helper.c | 44 +++++++++++++++++++++++----------- target/e2k/helper.h | 1 + target/e2k/translate/control.c | 8 +++---- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/target/e2k/helper.c b/target/e2k/helper.c index df2bba175b..2cc7f8d959 100644 --- a/target/e2k/helper.c +++ b/target/e2k/helper.c @@ -16,7 +16,8 @@ static inline void reset_ctprs(CPUE2KState *env) } } -static inline void save_proc_chain_info(CPUE2KState *env, uint64_t buf[4]) +static inline void save_proc_chain_info(CPUE2KState *env, uint64_t buf[4], + int wbs) { env->cr1.br = e2k_state_br(env); env->cr1.wpsz = env->wd.psize / 2; @@ -25,10 +26,17 @@ static inline void save_proc_chain_info(CPUE2KState *env, uint64_t buf[4]) buf[1] = env->cr0_hi; buf[2] = e2k_state_cr1_lo(env); buf[3] = e2k_state_cr1_hi(env); + + env->cr1.wfx = env->wd.fx; + env->cr1.wbs = wbs; + env->wd.base = (env->wd.base + wbs * 2) % WREGS_SIZE; + env->wd.psize = env->wd.size -= wbs * 2; } static inline void restore_proc_chain_info(CPUE2KState *env, uint64_t buf[4]) { + env->wd.fx = env->cr1.wfx; + e2k_state_cr1_hi_set(env, buf[3]); e2k_state_cr1_lo_set(env, buf[2]); env->cr0_hi = buf[1]; @@ -47,11 +55,8 @@ static void pcs_push(CPUE2KState *env, int wbs) return; } - // save proc chain - save_proc_chain_info(env, buf); + save_proc_chain_info(env, buf, wbs); memcpy(env->pcsp.base + env->pcsp.index, buf, 32); - - env->cr1.wbs = wbs; env->pcsp.index += 32; } @@ -152,17 +157,11 @@ static void ps_pop_fx(CPUE2KState *env, unsigned int base, size_t len) } } -static inline void do_call(CPUE2KState *env, int call_wbs) +static inline void do_call(CPUE2KState *env, int wbs) { - int call_wpsz = env->wd.size / 2 - call_wbs; - env->ip = env->nip; - pcs_push(env, call_wbs); - ps_push_nfx(env, env->wd.base, call_wbs * 2); - - env->wd.base = (env->wd.base + call_wbs * 2) % WREGS_SIZE; - env->wd.size = env->wd.psize = call_wpsz * 2; - + ps_push_nfx(env, env->wd.base, wbs * 2); + pcs_push(env, wbs); reset_ctprs(env); } @@ -341,3 +340,20 @@ uint64_t helper_getsp(CPUE2KState *env, uint64_t src2) { return base; } + +void helper_setwd(CPUE2KState *env, uint32_t lts) +{ + int wsz = extract32(lts, 5, 7); + bool nfx = extract32(lts, 4, 1); + + env->wd.size = wsz * 2; + env->wd.fx = nfx == 0; + + if (env->version >= 3) { + bool dbl = extract32(lts, 3, 1); + // TODO: set dbl + if (dbl != false) { + abort(); + } + } +} diff --git a/target/e2k/helper.h b/target/e2k/helper.h index a0a48e05f0..fbd1879410 100644 --- a/target/e2k/helper.h +++ b/target/e2k/helper.h @@ -8,3 +8,4 @@ DEF_HELPER_2(state_reg_get, i64, env, int) DEF_HELPER_3(state_reg_set, void, env, int, i64) DEF_HELPER_2(getsp, i64, env, i64) /* FIXME: return tl? */ DEF_HELPER_1(break_restore_state, void, env) +DEF_HELPER_2(setwd, void, env, i32) diff --git a/target/e2k/translate/control.c b/target/e2k/translate/control.c index 382984a2b5..dc855039d8 100644 --- a/target/e2k/translate/control.c +++ b/target/e2k/translate/control.c @@ -375,13 +375,11 @@ static void gen_cs1(DisasContext *dc) if (! bundle->lts_present[0]) { e2k_gen_exception(dc, E2K_EXCP_ILLOPC); } else { - uint32_t lts0 = bundle->lts[0]; - int wsz = GET_FIELD(lts0, 5, 7); - TCGv_i32 t0 = tcg_const_i32(lts0); + TCGv_i32 lts = tcg_const_i32(bundle->lts[0]); - tcg_gen_movi_i32(e2k_cs.wd_size, wsz * 2); + gen_helper_setwd(cpu_env, lts); - tcg_temp_free_i32(t0); + tcg_temp_free_i32(lts); } }