target: e2k: Save PC before reading it in rr{s,d}.
This commit is contained in:
parent
8028167de5
commit
728e400620
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user