From 53bb2d49eb3ef9f3d805f299fbf7368d85938583 Mon Sep 17 00:00:00 2001 From: Denis Drakhnya Date: Tue, 19 Jan 2021 13:19:43 +0200 Subject: [PATCH] e2k: Small performance improvements. Do not initialize alops_map for every tb. Reduced alops size. Delayed window bounds checks. --- target/e2k/translate.c | 31 ++++++++++++++++++++++++++++++- target/e2k/translate.h | 18 ++++++++++++++---- target/e2k/translate/aau.c | 4 ++-- target/e2k/translate/alc.c | 19 ++++++++++--------- target/e2k/translate/alops.inc | 8 ++++---- target/e2k/translate/state.c | 10 ---------- 6 files changed, 60 insertions(+), 30 deletions(-) diff --git a/target/e2k/translate.c b/target/e2k/translate.c index e227addd6a..dba7ce62df 100644 --- a/target/e2k/translate.c +++ b/target/e2k/translate.c @@ -246,6 +246,8 @@ static inline void do_reset(DisasContext *ctx) memset(ctx->mas, 0, sizeof(ctx->mas)); ctx->illtag = e2k_get_temp_i32(ctx); tcg_gen_movi_i32(ctx->illtag, 0); + ctx->max_wreg_cur = -1; + ctx->max_breg_cur = -1; } static inline target_ulong do_decode(DisasContext *ctx, CPUState *cs) @@ -290,6 +292,22 @@ static inline void do_execute(DisasContext *ctx) * */ static inline void do_commit(DisasContext *ctx) { + if (ctx->max_wreg < ctx->max_wreg_cur) { + TCGLabel *l0 = gen_new_label(); + ctx->max_wreg = ctx->max_wreg_cur; + tcg_gen_brcondi_i32(TCG_COND_GT, e2k_cs.wd_size, ctx->max_wreg, l0); + e2k_gen_exception(E2K_EXCP_MAPERR); + gen_set_label(l0); + } + + if (ctx->max_breg < ctx->max_breg_cur) { + TCGLabel *l0 = gen_new_label(); + ctx->max_breg = ctx->max_breg_cur; + tcg_gen_brcondi_i32(TCG_COND_GT, e2k_cs.bsize, ctx->max_breg, l0); + e2k_gen_exception(E2K_EXCP_MAPERR); + gen_set_label(l0); + } + e2k_control_window_change(ctx); e2k_alc_commit(ctx); e2k_aau_commit(ctx); @@ -361,12 +379,23 @@ static inline void do_branch(DisasContext *ctx, target_ulong pc_next) static void e2k_tr_init_disas_context(DisasContextBase *db, CPUState *cs) { + static int version = -1; DisasContext *ctx = container_of(db, DisasContext, base); E2KCPU *cpu = E2K_CPU(cs); CPUE2KState *env = &cpu->env; ctx->version = env->version; - e2k_alc_init(ctx); + ctx->max_wreg = -1; + ctx->max_breg = -1; + + if (version != ctx->version) { + if (version > 0) { + // FIXME: can it happen? + e2k_todo(ctx, "reinitialize alc map"); + } + alc_init(ctx); + version = ctx->version; + } } static void e2k_tr_tb_start(DisasContextBase *db, CPUState *cs) diff --git a/target/e2k/translate.h b/target/e2k/translate.h index 5435ba1f0d..2e6c4b5899 100644 --- a/target/e2k/translate.h +++ b/target/e2k/translate.h @@ -210,6 +210,12 @@ typedef struct DisasContext { int t64_len; int ttl_len; + /* Delayed window bounds checks */ + int max_wreg; + int max_wreg_cur; + int max_breg; + int max_breg_cur; + /* illegal tag for delayed exception */ TCGv_i32 illtag; TCGv_i64 cond[6]; @@ -482,12 +488,16 @@ void e2k_gen_reg_tag_check_i32(TCGv_i32 ret, TCGv_i32 tag); void e2k_gen_reg_index_from_wregi(TCGv_i32 ret, int idx); void e2k_gen_reg_index_from_bregi(TCGv_i32 ret, int idx); void e2k_gen_reg_index_from_gregi(TCGv_i32 ret, int idx); -static inline void e2k_gen_reg_index(TCGv_i32 ret, uint8_t arg) +static inline void e2k_gen_reg_index(DisasContext *ctx, TCGv_i32 ret, uint8_t arg) { if (IS_BASED(arg)) { - e2k_gen_reg_index_from_bregi(ret, GET_BASED(arg)); + int index = GET_BASED(arg); + ctx->max_breg_cur = MAX(ctx->max_breg_cur, index); + e2k_gen_reg_index_from_bregi(ret, index); } else if (IS_REGULAR(arg)) { - e2k_gen_reg_index_from_wregi(ret, GET_REGULAR(arg)); + int index = GET_REGULAR(arg); + ctx->max_wreg_cur = MAX(ctx->max_wreg_cur, index); + e2k_gen_reg_index_from_wregi(ret, index); } else if (IS_GLOBAL(arg)) { e2k_gen_reg_index_from_gregi(ret, GET_GLOBAL(arg)); } else { @@ -564,7 +574,7 @@ void e2k_control_execute(DisasContext *ctx); void e2k_control_window_change(DisasContext *ctx); void e2k_stubs_commit(DisasContext *ctx); -void e2k_alc_init(DisasContext *ctx); +void alc_init(DisasContext *ctx); void e2k_alc_execute(DisasContext *ctx); void e2k_alc_commit(DisasContext *ctx); diff --git a/target/e2k/translate/aau.c b/target/e2k/translate/aau.c index 36ca1d8f92..f70dfae74c 100644 --- a/target/e2k/translate/aau.c +++ b/target/e2k/translate/aau.c @@ -34,7 +34,7 @@ static void gen_aau_result_reg64(DisasContext *ctx, Instr *instr, TCGv_i64 dst) res->dst = instr->dst; } else { res->dst = 0; - e2k_gen_reg_index(res->index, instr->dst); + e2k_gen_reg_index(ctx, res->index, instr->dst); } } @@ -49,7 +49,7 @@ static void gen_aau_result_reg32(DisasContext *ctx, Instr *instr, TCGv_i32 dst) res->dst = instr->dst; } else { res->dst = 0; - e2k_gen_reg_index(res->index, instr->dst); + e2k_gen_reg_index(ctx, res->index, instr->dst); } } diff --git a/target/e2k/translate/alc.c b/target/e2k/translate/alc.c index 761c781ba7..e35ffde1d8 100644 --- a/target/e2k/translate/alc.c +++ b/target/e2k/translate/alc.c @@ -142,7 +142,7 @@ static inline void gen_reg_i80(DisasContext *ctx, Src80 *ret, uint8_t arg) { TCGv_i32 t0 = tcg_temp_new_i32(); - e2k_gen_reg_index(t0, arg); + e2k_gen_reg_index(ctx, t0, arg); ret->tag = e2k_get_temp_i32(ctx); ret->lo = e2k_get_temp_i64(ctx); ret->hi = e2k_get_temp_i32(ctx); @@ -156,7 +156,7 @@ static inline void gen_reg_i64(DisasContext *ctx, Src64 *ret, uint8_t arg) { TCGv_i32 t0 = tcg_temp_new_i32(); - e2k_gen_reg_index(t0, arg); + e2k_gen_reg_index(ctx, t0, arg); ret->tag = e2k_get_temp_i32(ctx); ret->value = e2k_get_temp_i64(ctx); e2k_gen_reg_tag_read_i64(ret->tag, t0); @@ -169,7 +169,7 @@ static inline void gen_reg_i32(DisasContext *ctx, Src32 *ret, uint8_t arg) { TCGv_i32 t0 = tcg_temp_new_i32(); - e2k_gen_reg_index(t0, arg); + e2k_gen_reg_index(ctx, t0, arg); ret->tag = e2k_get_temp_i32(ctx); ret->value = e2k_get_temp_i32(ctx); e2k_gen_reg_tag_read_i32(ret->tag, t0); @@ -488,7 +488,7 @@ static inline void set_al_result_reg80_tag(Instr *instr, TCGv_i64 lo, res->reg.index = get_temp_i32(instr); res->reg.dst = dst; if (!IS_REGULAR(dst)) { - e2k_gen_reg_index(res->reg.index, dst); + e2k_gen_reg_index(instr->ctx, res->reg.index, dst); } } } @@ -521,7 +521,7 @@ static inline void set_al_result_reg64_tag(Instr *instr, res->reg.dst = arg; } else { res->reg.dst = 0; - e2k_gen_reg_index(res->reg.index, arg); + e2k_gen_reg_index(instr->ctx, res->reg.index, arg); } } } @@ -560,7 +560,7 @@ static inline void set_al_result_reg32_tag(Instr *instr, res->reg.dst = arg; } else { res->reg.dst = 0; - e2k_gen_reg_index(res->reg.index, arg); + e2k_gen_reg_index(instr->ctx, res->reg.index, arg); } } } @@ -1659,7 +1659,7 @@ static inline void gen_ld_mas_mod(DisasContext *ctx, Instr *instr, TCGv_i32 reg = tcg_temp_new_i32(); // FIXME: %empty - e2k_gen_reg_index(reg, instr->dst); + e2k_gen_reg_index(instr->ctx, reg, instr->dst); size = tcg_const_i32(1 << (instr->opc1 - 0x64)); switch (mod) { @@ -4579,7 +4579,7 @@ static void chan_execute(DisasContext *ctx, int chan) void e2k_alc_execute(DisasContext *ctx) { - unsigned int i; + int i; for (i = 0; i < 6; i++) { ctx->al_results[i].type = AL_RESULT_NONE; @@ -4757,7 +4757,8 @@ void e2k_alc_commit(DisasContext *ctx) } } -void e2k_alc_init(DisasContext *ctx) + +void alc_init(DisasContext *ctx) { int i, j; diff --git a/target/e2k/translate/alops.inc b/target/e2k/translate/alops.inc index f33488ddc1..51dfb46d44 100644 --- a/target/e2k/translate/alops.inc +++ b/target/e2k/translate/alops.inc @@ -946,14 +946,14 @@ typedef enum { } AlopExt; typedef struct { - Alop op; - Alopf alopf; + uint16_t op; + uint8_t alopf; AlopArgs format; - AlopExt opc2; + uint8_t opc2; uint8_t opc1; uint8_t min_version; uint8_t max_version; - Channels channels; + uint8_t channels; int16_t next[6]; uint8_t extra1; /* opce1, opce2, cmpopce */ uint8_t extra2; /* opce2, implicit_nops, explicit_ales25_v4 */ diff --git a/target/e2k/translate/state.c b/target/e2k/translate/state.c index 09952eaa30..d028c75b69 100644 --- a/target/e2k/translate/state.c +++ b/target/e2k/translate/state.c @@ -204,17 +204,12 @@ void e2k_gen_reg_tag_write_i32(TCGv_i32 value, TCGv_i32 idx) static inline void gen_reg_index_from_wreg(TCGv_i32 ret, TCGv_i32 idx) { - TCGLabel *l0 = gen_new_label(); TCGv_i32 t0 = tcg_temp_local_new_i32(); TCGv_i32 t1 = tcg_temp_new_i32(); TCGv_i32 t2; tcg_gen_mov_i32(t0, idx); - tcg_gen_brcond_i32(TCG_COND_LTU, t0, e2k_cs.wd_size, l0); - e2k_gen_exception(E2K_EXCP_MAPERR); - gen_set_label(l0); - tcg_gen_add_i32(t1, e2k_cs.wd_base, t0); tcg_temp_free_i32(t0); t2 = tcg_const_i32(E2K_NR_COUNT); @@ -232,15 +227,10 @@ void e2k_gen_reg_index_from_wregi(TCGv_i32 ret, int idx) void e2k_gen_reg_index_from_bregi(TCGv_i32 ret, int idx) { - TCGLabel *l0 = gen_new_label(); TCGv_i32 t0 = tcg_temp_new_i32(); TCGv_i32 t1 = tcg_temp_new_i32(); TCGv_i32 t2 = tcg_temp_new_i32(); - tcg_gen_brcondi_i32(tcg_invert_cond(TCG_COND_LTU), e2k_cs.bsize, idx, l0); - e2k_gen_exception(E2K_EXCP_MAPERR); - gen_set_label(l0); - tcg_gen_addi_i32(t0, e2k_cs.bcur, idx); tcg_gen_remu_i32(t1, t0, e2k_cs.bsize); tcg_temp_free_i32(t0);