diff --git a/target/e2k/gdbstub.c b/target/e2k/gdbstub.c index cc45c6cd93..e77841bdf8 100644 --- a/target/e2k/gdbstub.c +++ b/target/e2k/gdbstub.c @@ -209,11 +209,23 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) } if (356 <= n && n < 360) { - return gdb_get_reg64(mem_buf, 0); // gN tags (tag len is 1 byte) + uint64_t tags = 0; + int i, offset = E2K_NR_COUNT + (n - 356) * 8; + + for (i = 0; i < 8; i++) { + tags |= (uint64_t) env->tags[offset + i] << (i * 8); + } + return gdb_get_reg64(mem_buf, tags); // gN tags (tag len is 1 byte) } if (360 <= n && n < 368) { - return gdb_get_reg64(mem_buf, 0); // xgN + uint64_t ext = 0; + int i, offset = E2K_NR_COUNT + (n - 360) * 4; + + for (i = 0; i < 4; i++) { + ext |= ((uint64_t) env->regs[offset + i].hi & 0xffff) << (i * 16); + } + return gdb_get_reg64(mem_buf, ext); // xgN } if (n == 368) { diff --git a/target/e2k/helper.c b/target/e2k/helper.c index f4d63b0d28..ffa2aafca0 100644 --- a/target/e2k/helper.c +++ b/target/e2k/helper.c @@ -318,7 +318,7 @@ void HELPER(setwd)(CPUE2KState *env, int wsz, int nfx, int dbl) memset(&env->regs[env->wd.size], 0, diff * sizeof(env->regs[0])); #endif #ifdef E2K_TAGS_ENABLE - memset(&env->tags[env->wd.size], E2K_TAG_NON_NUMBER64, diff); + memset(&env->tags[env->wd.size], E2K_TAG_NON_NUMBER128, diff); #endif } diff --git a/target/e2k/translate.c b/target/e2k/translate.c index 612063b8ef..5dcda27e9c 100644 --- a/target/e2k/translate.c +++ b/target/e2k/translate.c @@ -504,6 +504,9 @@ typedef struct DisasContext { /* optional, can be NULL */ TCGv_i32 mlock; TCGv_i32 loop_end; +#ifdef E2K_TAGS_ENABLE + TCGv_i32 delayed_illop; +#endif int version; /* Force ILLOP for bad instruction format for cases where real CPU @@ -1876,7 +1879,7 @@ static bool is_alop_affected_by_dbl(Alop *alop) return true; } -#if 0 +#ifdef E2K_TAGS_ENABLE static bool is_alop_check_tag(Alop *alop) { if (alop->format == ALOPF2) { @@ -1897,7 +1900,9 @@ static bool is_alop_check_tag(Alop *alop) return true; } +#endif +#if 0 static bool is_alop_poison_result(Alop *alop) { if (alop->format == ALOPF2) { @@ -2428,25 +2433,28 @@ static void gen_reg_set_s(DisasContext *ctx, bool is_dbl, TCGv_ptr t0 = tcg_temp_local_new_ptr(); TCGv_i32 t1 = tcg_temp_local_new_i32(); TCGv_i64 t2 = tcg_temp_local_new_i64(); + TCGv_i32 t3 = tcg_temp_local_new_i32(); gen_reg_lo_ptr(t0, index); tcg_gen_mov_i32(t1, tag); tcg_gen_mov_i64(t2, val); + tcg_gen_mov_i32(t3, index); tcg_gen_brcondi_i32(TCG_COND_NE, cpu_wdbl, 0, l0); /* wdbl is not set */ - gen_reg_tag_set_i32(ctx, t1, index); + gen_reg_tag_set_i32(ctx, t1, t3); tcg_gen_st32_i64(t2, t0, 0); tcg_gen_br(l1); /* wdbl is set */ gen_set_label(l0); gen_tag1_i64(t1, t1); - gen_reg_tag_set_i64(ctx, t1, index); + gen_reg_tag_set_i64(ctx, t1, t3); tcg_gen_st_i64(t2, t0, 0); gen_set_label(l1); + tcg_temp_free_i32(t3); tcg_temp_free_i64(t2); tcg_temp_free_i32(t1); tcg_temp_free_ptr(t0); @@ -2462,10 +2470,34 @@ static void gen_reg_set_s(DisasContext *ctx, bool is_dbl, } } +#ifdef E2K_TAGS_ENABLE +static void gen_delayed_tag_check(DisasContext *ctx, TCGv_i32 tag) +{ + TCGv_i32 t0 = tcg_temp_new_i32(); + + tcg_gen_setcondi_i32(TCG_COND_NE, t0, tag, 0); + tcg_gen_or_i32(ctx->delayed_illop, ctx->delayed_illop, t0); + tcg_temp_free_i32(t0); +} + +static inline void gen_delayed_alop_tag_check(Alop *alop, TCGv_i32 tag) +{ + if (!alop->als.sm && is_alop_check_tag(alop)) { + gen_delayed_tag_check(alop->ctx, tag); + } +} +#else +static inline void gen_delayed_alop_tag_check(Alop *alop, TCGv_i32 tag) +{ +} +#endif + static void gen_al_result_q(Alop *alop, Tagged_ptr arg) { uint8_t dst = alop->als.dst; + gen_delayed_alop_tag_check(alop, arg.tag); + if (dst == 0xdf) { /* %empty */ } else if (IS_REG(dst)) { @@ -2484,6 +2516,8 @@ static void gen_al_result_x(Alop *alop, Tagged_ptr arg) { uint8_t dst = alop->als.dst; + gen_delayed_alop_tag_check(alop, arg.tag); + if (dst == 0xdf) { /* %empty */ } else if (IS_REG(dst)) { @@ -2502,6 +2536,8 @@ static void gen_al_result_d(Alop *alop, Tagged_i64 arg) { uint8_t dst = alop->als.dst; + gen_delayed_alop_tag_check(alop, arg.tag); + if (dst == 0xdf) { /* %empty */ } else if (IS_REG(dst)) { @@ -2533,6 +2569,8 @@ static void gen_al_result_s(Alop *alop, Tagged_i32 arg) { uint8_t dst = alop->als.dst; + gen_delayed_alop_tag_check(alop, arg.tag); + if (dst == 0xdf) { /* %empty */ } else if (IS_REG(dst)) { @@ -2564,7 +2602,6 @@ static void gen_al_result_s(Alop *alop, Tagged_i32 arg) static void gen_al_result_b(Alop *alop, Tagged_i32 arg) { - // TODO: preg tag gen_preg_set_i32(alop->als.dst_preg, arg.val); } @@ -6704,7 +6741,7 @@ static void gen_alop_pred(Alop *alop, TCGLabel *l) tcg_temp_free_i32(t0); } -static void alop_decode(Alop *alop, AlesFlag ales_present) +static void decode_alop(Alop *alop, AlesFlag ales_present) { DisasContext *ctx = alop->ctx; @@ -6935,7 +6972,7 @@ static void decode_alops(DisasContext *ctx) alop->als.raw = ctx->bundle.als[i]; alop->ales.raw = ctx->bundle.ales[i]; - alop_decode(alop, ctx->bundle.ales_present[i]); + decode_alop(alop, ctx->bundle.ales_present[i]); } } } @@ -7293,14 +7330,6 @@ static inline void gen_setbp(DisasContext *ctx) } } -static inline void gen_setr(DisasContext *ctx) -{ - gen_vfrpsz(ctx); - gen_setwd(ctx); - gen_setbn(ctx); - gen_setbp(ctx); -} - static inline void gen_cs1(DisasContext *ctx) { Cs1 *cs1 = &ctx->cs1; @@ -7770,14 +7799,25 @@ static void gen_loop_end_init(DisasContext *ctx) } } -static inline void do_branch(DisasContext *ctx, target_ulong pc_next) +static void do_branch(DisasContext *ctx, target_ulong pc_next) { + /* FIXME: save PC only when necessary. */ + gen_save_pc(ctx->base.pc_next); + +#ifdef E2K_TAGS_ENABLE + { + TCGLabel *l0 = gen_new_label(); + tcg_gen_brcondi_i32(TCG_COND_EQ, ctx->delayed_illop, 0, l0); + gen_excp_illopc(); + gen_set_label(l0); + } +#endif + if (ctx->ct.type == CT_NONE) { return; } ctx->base.is_jmp = DISAS_NORETURN; - gen_save_pc(ctx->base.pc_next); if (ctx->ct.cond_type > 1) { TCGLabel *l0 = gen_new_label(); @@ -7873,8 +7913,12 @@ static void e2k_tr_insn_start(DisasContextBase *db, CPUState *cs) tcg_gen_insn_start(ctx->base.pc_next); ctx->cs0.type = CS0_NONE; - ctx->cs1.type = CS0_NONE; + ctx->cs1.type = CS1_NONE; ctx->mlock = NULL; +#ifdef E2K_TAGS_ENABLE + ctx->delayed_illop = e2k_get_temp_i32(ctx); + tcg_gen_movi_i32(ctx->delayed_illop, 0); +#endif ctx->saved_reg_len = 0; ctx->saved_preg_len = 0; } @@ -7929,6 +7973,7 @@ static void e2k_tr_translate_insn(DisasContextBase *db, CPUState *cs) ctx->loop_mode = (ctx->bundle.hs & (1 << 10)) != 0; gen_alop_reg_indices_check(ctx); + gen_setwd(ctx); gen_cs0(ctx); gen_cs1(ctx); gen_mlock_init(ctx); @@ -7937,7 +7982,9 @@ static void e2k_tr_translate_insn(DisasContextBase *db, CPUState *cs) gen_aau(ctx); gen_plu(ctx); gen_ct_cond(ctx); - gen_setr(ctx); + gen_vfrpsz(ctx); + gen_setbn(ctx); + gen_setbp(ctx); gen_stubs(ctx); do_branch(ctx, pc_next); break;