e2k: Restore basic tags support.

Disabled at compile time.
This commit is contained in:
Denis Drakhnia 2021-03-24 14:32:23 +02:00 committed by Denis Drakhnia
parent 0c634e952b
commit d84636d73a
3 changed files with 80 additions and 21 deletions

View File

@ -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) {

View File

@ -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
}

View File

@ -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;