No longer used hacked liveness_pass_1
This hack was introduced in issue#287 which later becomes endless maintainance pain. ===== Our previous check_exit_request use `brcond` in the middle of a TranslationBlock which breaks the assumptions and thus a hack to liveness_pass_1 is used for _all_ brcond instructions which causes issues for MIPS and many other scenarios. ===== This patch also resolves PC not sync-ed when no memory hooks are installed, finally. Now Unicorn will always have correct PC no matter what happens.
This commit is contained in:
@@ -2852,8 +2852,6 @@ static void gen_ldst_i64(TCGContext *tcg_ctx, TCGOpcode opc, TCGv_i64 val, TCGv
|
||||
// if so, we jump to the block epilogue to quit immediately.
|
||||
void check_exit_request(TCGContext *tcg_ctx)
|
||||
{
|
||||
TCGv_i32 count;
|
||||
|
||||
// Unicorn:
|
||||
// For ARM IT block, we couldn't exit in the middle of the
|
||||
// block and this is the our hack here.
|
||||
@@ -2861,23 +2859,17 @@ void check_exit_request(TCGContext *tcg_ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
count = tcg_temp_new_i32(tcg_ctx);
|
||||
|
||||
tcg_gen_ld_i32(tcg_ctx, count, tcg_ctx->cpu_env,
|
||||
offsetof(ArchCPU, neg.icount_decr.u32) -
|
||||
offsetof(ArchCPU, env));
|
||||
TCGv_ptr puc = tcg_const_ptr(tcg_ctx, tcg_ctx->uc);
|
||||
TCGv_i32 tmp = tcg_const_i32(tcg_ctx, 0);
|
||||
// Unicorn:
|
||||
// We CANT'T use brcondi_i32 here or we will fail liveness analysis
|
||||
// because it marks the end of BB
|
||||
if (tcg_ctx->delay_slot_flag != NULL) {
|
||||
TCGv_i32 tmp = tcg_const_i32(tcg_ctx, 0);
|
||||
// dest = (c1 cond c2 ? v1 : v2)
|
||||
tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GT, count, tcg_ctx->delay_slot_flag, tmp, tcg_ctx->delay_slot_flag, count);
|
||||
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||
tcg_gen_mov_i32(tcg_ctx, tmp, tcg_ctx->delay_slot_flag);
|
||||
}
|
||||
|
||||
tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_LT, count, 0, tcg_ctx->exitreq_label);
|
||||
tcg_temp_free_i32(tcg_ctx, count);
|
||||
gen_helper_check_exit_request(tcg_ctx, puc, tmp);
|
||||
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||
tcg_temp_free_ptr(tcg_ctx, puc);
|
||||
}
|
||||
|
||||
static void tcg_gen_req_mo(TCGContext *tcg_ctx, TCGBar type)
|
||||
|
||||
@@ -2243,17 +2243,6 @@ static inline void la_reset_pref(TCGContext *tcg_ctx, TCGTemp *ts)
|
||||
= (ts->state == TS_DEAD ? 0 : tcg_ctx->tcg_target_available_regs[ts->type]);
|
||||
}
|
||||
|
||||
/*
|
||||
Unicorn: for brcond, we should refresh liveness states for TCG globals
|
||||
*/
|
||||
static void la_brcond_end(TCGContext *s, int ng)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ng; i++) {
|
||||
s->temps[i].state |= TS_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* liveness analysis: end of function: all temps are dead, and globals
|
||||
should be in memory. */
|
||||
@@ -2581,20 +2570,7 @@ static void liveness_pass_1(TCGContext *s)
|
||||
if (def->flags & TCG_OPF_BB_EXIT) {
|
||||
la_func_end(s, nb_globals, nb_temps);
|
||||
} else if (def->flags & TCG_OPF_BB_END) {
|
||||
// Unicorn: do not optimize dead temps on brcond,
|
||||
// this causes problem because check_exit_request() inserts
|
||||
// brcond instruction in the middle of the TB,
|
||||
// which incorrectly flags end-of-block
|
||||
if (opc != INDEX_op_brcond_i32) {
|
||||
la_bb_end(s, nb_globals, nb_temps);
|
||||
} else {
|
||||
// Unicorn: we do not touch dead temps for brcond,
|
||||
// but we should refresh TCG globals In-Memory states,
|
||||
// otherwise, important CPU states(especially conditional flags) might be forgotten,
|
||||
// result in wrongly generated host code that run into wrong branch.
|
||||
// Refer to https://github.com/unicorn-engine/unicorn/issues/287 for further information
|
||||
la_brcond_end(s, nb_globals);
|
||||
}
|
||||
la_bb_end(s, nb_globals, nb_temps);
|
||||
} else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
|
||||
la_global_sync(s, nb_globals);
|
||||
if (def->flags & TCG_OPF_CALL_CLOBBER) {
|
||||
|
||||
Reference in New Issue
Block a user