target: e2k: Save PC before reading it in rr{s,d}.

This commit is contained in:
Denis Drakhnia 2020-12-12 20:22:38 +02:00 committed by Denis Drakhnia
parent 8028167de5
commit 728e400620
3 changed files with 31 additions and 35 deletions

View File

@ -186,16 +186,6 @@ static size_t unpack_bundle(CPUE2KState *env, DisasContext *ctx)
return 8 + GET_FIELD(hs, 4, 3) * 8; return 8 + GET_FIELD(hs, 4, 3) * 8;
} }
static inline void gen_save_pc(target_ulong pc)
{
tcg_gen_movi_tl(e2k_cs.pc, pc);
}
static inline void gen_save_cpu_state(DisasContext *ctx)
{
gen_save_pc(ctx->pc);
}
static void gen_goto_tb(DisasContext *ctx, int tb_num, target_ulong pc) static void gen_goto_tb(DisasContext *ctx, int tb_num, target_ulong pc)
{ {
if (translator_use_goto_tb(&ctx->base, pc)) { if (translator_use_goto_tb(&ctx->base, pc)) {
@ -214,7 +204,7 @@ void e2k_tr_gen_exception(DisasContext *ctx, int which)
{ {
TCGv_i32 t = tcg_const_i32(which); TCGv_i32 t = tcg_const_i32(which);
gen_save_cpu_state(ctx); e2k_gen_save_cpu_state(ctx);
gen_helper_raise_exception(cpu_env, t); gen_helper_raise_exception(cpu_env, t);
ctx->base.is_jmp = DISAS_NORETURN; ctx->base.is_jmp = DISAS_NORETURN;

View File

@ -303,6 +303,16 @@ static inline TCGv e2k_get_temp(DisasContext *dc)
return dc->ttl[dc->ttl_len++] = tcg_temp_local_new(); return dc->ttl[dc->ttl_len++] = tcg_temp_local_new();
} }
static inline void e2k_gen_save_pc(target_ulong pc)
{
tcg_gen_movi_tl(e2k_cs.pc, pc);
}
static inline void e2k_gen_save_cpu_state(DisasContext *ctx)
{
e2k_gen_save_pc(ctx->pc);
}
static inline void e2k_gen_lcnt_i64(TCGv_i64 ret) static inline void e2k_gen_lcnt_i64(TCGv_i64 ret)
{ {
tcg_gen_andi_i64(ret, e2k_cs.lsr, (1UL << 32) - 1); tcg_gen_andi_i64(ret, e2k_cs.lsr, (1UL << 32) - 1);

View File

@ -1264,48 +1264,44 @@ static inline void gen_smulhd(TCGv_i64 ret, TCGv_i64 src1, TCGv_i64 src2)
tcg_temp_free_i64(t0); tcg_temp_free_i64(t0);
} }
static inline void gen_rr_i64(DisasContext *ctx, int chan) static inline void gen_rr_i64(DisasContext *ctx, Instr *instr)
{ {
uint32_t als = ctx->bundle.als[chan];
uint8_t state_reg = extract32(als, 16, 8);
TCGv_i64 dst = e2k_get_temp_i64(ctx); TCGv_i64 dst = e2k_get_temp_i64(ctx);
TCGv_i32 t0 = tcg_const_i32(state_reg); TCGv_i32 t0 = tcg_const_i32(instr->src1);
e2k_gen_save_cpu_state(ctx);
gen_helper_state_reg_read_i64(dst, cpu_env, t0); gen_helper_state_reg_read_i64(dst, cpu_env, t0);
set_al_result_reg64(ctx, chan, dst); set_al_result_reg64(ctx, instr->chan, dst);
tcg_temp_free_i32(t0); tcg_temp_free_i32(t0);
} }
static inline void gen_rr_i32(DisasContext *ctx, int chan) static inline void gen_rr_i32(DisasContext *ctx, Instr *instr)
{ {
uint32_t als = ctx->bundle.als[chan];
uint8_t state_reg = extract32(als, 16, 8);
TCGv_i32 dst = e2k_get_temp_i32(ctx); TCGv_i32 dst = e2k_get_temp_i32(ctx);
TCGv_i32 t0 = tcg_const_i32(state_reg); TCGv_i32 t0 = tcg_const_i32(instr->src1);
e2k_gen_save_cpu_state(ctx);
gen_helper_state_reg_read_i32(dst, cpu_env, t0); gen_helper_state_reg_read_i32(dst, cpu_env, t0);
set_al_result_reg32(ctx, chan, dst); set_al_result_reg32(ctx, instr->chan, dst);
tcg_temp_free_i32(t0); tcg_temp_free_i32(t0);
} }
static inline void gen_rw_i64(DisasContext *ctx, int chan) static inline void gen_rw_i64(DisasContext *ctx, Instr *instr)
{ {
uint32_t als = ctx->bundle.als[chan]; Src64 s2 = get_src2_i64(ctx, instr->chan);
Src64 s2 = get_src2_i64(ctx, chan); TCGv_i32 t0 = tcg_const_i32(instr->dst);
TCGv_i32 t0 = tcg_const_i32(als & 0xff);
gen_tag_check(ctx, als >> 31, s2.tag); gen_tag_check(ctx, instr->sm, s2.tag);
gen_helper_state_reg_write_i64(cpu_env, t0, s2.value); gen_helper_state_reg_write_i64(cpu_env, t0, s2.value);
tcg_temp_free_i32(t0); tcg_temp_free_i32(t0);
} }
static inline void gen_rw_i32(DisasContext *ctx, int chan) static inline void gen_rw_i32(DisasContext *ctx, Instr *instr)
{ {
uint32_t als = ctx->bundle.als[chan]; Src32 s2 = get_src2_i32(ctx, instr->chan);
Src32 s2 = get_src2_i32(ctx, chan); TCGv_i32 t0 = tcg_const_i32(instr->dst);
TCGv_i32 t0 = tcg_const_i32(als & 0xff);
gen_tag_check(ctx, als >> 31, s2.tag); gen_tag_check(ctx, instr->sm, s2.tag);
gen_helper_state_reg_write_i32(cpu_env, t0, s2.value); gen_helper_state_reg_write_i32(cpu_env, t0, s2.value);
tcg_temp_free_i32(t0); tcg_temp_free_i32(t0);
} }
@ -2282,28 +2278,28 @@ static void execute_ext_01(DisasContext *ctx, Instr *instr)
case 0x3c: case 0x3c:
if (chan == 0) { if (chan == 0) {
/* rws */ /* rws */
gen_rw_i32(ctx, chan); gen_rw_i32(ctx, instr);
return; return;
} }
break; break;
case 0x3d: case 0x3d:
if (chan == 0) { if (chan == 0) {
/* rwd */ /* rwd */
gen_rw_i64(ctx, chan); gen_rw_i64(ctx, instr);
return; return;
} }
break; break;
case 0x3e: case 0x3e:
if (chan == 0) { if (chan == 0) {
/* rrs */ /* rrs */
gen_rr_i32(ctx, chan); gen_rr_i32(ctx, instr);
return; return;
} }
break; break;
case 0x3f: case 0x3f:
if (chan == 0) { if (chan == 0) {
/* rrd */ /* rrd */
gen_rr_i64(ctx, chan); gen_rr_i64(ctx, instr);
return; return;
} else if (is_chan_25(chan)) { } else if (is_chan_25(chan)) {
/* staaq */ /* staaq */