From 229797cfbdc7b9918da153d81767221958580796 Mon Sep 17 00:00:00 2001 From: Denis Drakhnya Date: Fri, 27 Nov 2020 00:03:54 +0200 Subject: [PATCH] target: e2k: Ps push/pop with pshtp. --- target/e2k/helper.c | 55 +++++++++++++++++++++++++++----------- target/e2k/translate/alc.c | 11 +++++--- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/target/e2k/helper.c b/target/e2k/helper.c index 2cc7f8d959..913eea8936 100644 --- a/target/e2k/helper.c +++ b/target/e2k/helper.c @@ -157,29 +157,55 @@ static void ps_pop_fx(CPUE2KState *env, unsigned int base, size_t len) } } +static inline void ps_push(CPUE2KState *env) +{ + int occupied = env->wd.size + env->pshtp.index; + if (WREGS_SIZE < occupied) { + int len = occupied - WREGS_SIZE; + int base = (int) env->wd.base - env->pshtp.index; + if (base < 0) { + base += WREGS_SIZE; + } + // TODO: ps_push_fx + ps_push_nfx(env, base, len); + env->pshtp.index -= len; + } +} + +static inline void ps_pop(CPUE2KState *env, int base, int required) +{ + if (env->pshtp.index < required) { + int len = required - env->pshtp.index; + // TODO: ps_pop_fx + ps_pop_nfx(env, base, len); + env->pshtp.index = 0; + } else { + env->pshtp.index -= required; + } +} + static inline void do_call(CPUE2KState *env, int wbs) { env->ip = env->nip; - ps_push_nfx(env, env->wd.base, wbs * 2); + env->pshtp.index += wbs * 2; // add old window to allocated registers pcs_push(env, wbs); reset_ctprs(env); } void helper_return(CPUE2KState *env) { - uint32_t new_wd_size, new_wd_base, wbs; + uint32_t new_wd_size, new_wd_base, offset; - wbs = env->cr1.wbs; - new_wd_size = env->wd.psize + wbs * 2; - new_wd_base = (env->wd.base - wbs * 2) % WREGS_SIZE; - - if (env->wd.base < new_wd_base) { - env->wd.base += WREGS_SIZE; + offset = env->cr1.wbs * 2; + new_wd_size = env->wd.psize + offset; + new_wd_base = env->wd.base; + if (new_wd_base < offset) { + new_wd_base += WREGS_SIZE; } + new_wd_base = (new_wd_base - offset) % WREGS_SIZE; - ps_pop_nfx(env, new_wd_base, env->wd.base - new_wd_base); + ps_pop(env, new_wd_base, offset); pcs_pop(env); - env->wd.base = new_wd_base; env->wd.size = new_wd_size; @@ -343,11 +369,8 @@ uint64_t helper_getsp(CPUE2KState *env, uint64_t src2) { 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; + env->wd.size = extract32(lts, 5, 7) * 2; + env->wd.fx = extract32(lts, 4, 1) == 0; if (env->version >= 3) { bool dbl = extract32(lts, 3, 1); @@ -356,4 +379,6 @@ void helper_setwd(CPUE2KState *env, uint32_t lts) abort(); } } + + ps_push(env); } diff --git a/target/e2k/translate/alc.c b/target/e2k/translate/alc.c index 30ca8a30d6..9d97734d7b 100644 --- a/target/e2k/translate/alc.c +++ b/target/e2k/translate/alc.c @@ -704,13 +704,16 @@ static void gen_alopf1_i64(DisasContext *dc, int chan, static void gen_alopf1_mrgc_i32(DisasContext *dc, int chan) { uint32_t als = dc->bundle.als[chan]; + TCGv_i64 src1 = get_src1(dc, als); + TCGv_i64 src2 = get_src2(dc, als); + TCGv_i64 dst = get_dst(dc, als); TCGv_i64 t0 = tcg_temp_new_i64(); TCGv_i64 t1 = e2k_get_temp_i64(dc); TCGv_i64 cond = tcg_temp_new_i64(); gen_mrgc_i64(dc, chan, cond); - gen_merge_i64(t0, get_src1(dc, als), get_src2(dc, als), cond); - gen_movehl_i64(t1, t0, get_dst(dc, als)); + gen_merge_i64(t0, src1, src2, cond); + gen_movehl_i64(t1, t0, dst); store_reg_alc_result(dc, chan, t1); tcg_temp_free_i64(cond); @@ -720,11 +723,13 @@ static void gen_alopf1_mrgc_i32(DisasContext *dc, int chan) static void gen_alopf1_mrgc_i64(DisasContext *dc, int chan) { uint32_t als = dc->bundle.als[chan]; + TCGv_i64 src1 = get_src1(dc, als); + TCGv_i64 src2 = get_src2(dc, als); TCGv_i64 t0 = e2k_get_temp_i64(dc); TCGv_i64 cond = tcg_temp_new_i64(); gen_mrgc_i64(dc, chan, cond); - gen_merge_i64(t0, get_src1(dc, als), get_src2(dc, als), cond); + gen_merge_i64(t0, src1, src2, cond); store_reg_alc_result(dc, chan, t0); tcg_temp_free_i64(cond);