tcg: synchronize globals for ops with side effects
Operations with side effects (in practice qemu_ld/st ops), only need to synchronize globals to make sure the CPU state is consistent in case of exception. Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
b202d41ee7
commit
3d5c5f876d
33
tcg/tcg.c
33
tcg/tcg.c
@ -1407,9 +1407,8 @@ static void tcg_liveness_analysis(TCGContext *s)
|
|||||||
/* if end of basic block, update */
|
/* if end of basic block, update */
|
||||||
if (def->flags & TCG_OPF_BB_END) {
|
if (def->flags & TCG_OPF_BB_END) {
|
||||||
tcg_la_bb_end(s, dead_temps, mem_temps);
|
tcg_la_bb_end(s, dead_temps, mem_temps);
|
||||||
} else if (def->flags & TCG_OPF_CALL_CLOBBER) {
|
} else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
|
||||||
/* globals should go back to memory */
|
/* globals should be synced to memory */
|
||||||
memset(dead_temps, 1, s->nb_globals);
|
|
||||||
memset(mem_temps, 1, s->nb_globals);
|
memset(mem_temps, 1, s->nb_globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1670,6 +1669,23 @@ static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sync globals to their canonical location and assume they can be
|
||||||
|
read by the following code. 'allocated_regs' is used in case a
|
||||||
|
temporary registers needs to be allocated to store a constant. */
|
||||||
|
static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < s->nb_globals; i++) {
|
||||||
|
#ifdef USE_LIVENESS_ANALYSIS
|
||||||
|
assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
|
||||||
|
s->temps[i].mem_coherent);
|
||||||
|
#else
|
||||||
|
temp_sync(s, i, allocated_regs);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* at the end of a basic block, we assume all temporaries are dead and
|
/* at the end of a basic block, we assume all temporaries are dead and
|
||||||
all globals are stored at their canonical location. */
|
all globals are stored at their canonical location. */
|
||||||
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
|
static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
|
||||||
@ -1907,12 +1923,11 @@ static void tcg_reg_alloc_op(TCGContext *s,
|
|||||||
tcg_reg_free(s, reg);
|
tcg_reg_free(s, reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* XXX: for load/store we could do that only for the slow path
|
}
|
||||||
(i.e. when a memory callback is called) */
|
if (def->flags & TCG_OPF_SIDE_EFFECTS) {
|
||||||
|
/* sync globals if the op has side effects and might trigger
|
||||||
/* store globals and free associated registers (we assume the insn
|
an exception. */
|
||||||
can modify any global. */
|
sync_globals(s, allocated_regs);
|
||||||
save_globals(s, allocated_regs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* satisfy the output constraints */
|
/* satisfy the output constraints */
|
||||||
|
@ -530,8 +530,8 @@ enum {
|
|||||||
TCG_OPF_BB_END = 0x01,
|
TCG_OPF_BB_END = 0x01,
|
||||||
/* Instruction clobbers call registers and potentially update globals. */
|
/* Instruction clobbers call registers and potentially update globals. */
|
||||||
TCG_OPF_CALL_CLOBBER = 0x02,
|
TCG_OPF_CALL_CLOBBER = 0x02,
|
||||||
/* Instruction has side effects: it cannot be removed
|
/* Instruction has side effects: it cannot be removed if its outputs
|
||||||
if its outputs are not used. */
|
are not used, and might trigger exceptions. */
|
||||||
TCG_OPF_SIDE_EFFECTS = 0x04,
|
TCG_OPF_SIDE_EFFECTS = 0x04,
|
||||||
/* Instruction operands are 64-bits (otherwise 32-bits). */
|
/* Instruction operands are 64-bits (otherwise 32-bits). */
|
||||||
TCG_OPF_64BIT = 0x08,
|
TCG_OPF_64BIT = 0x08,
|
||||||
|
Loading…
Reference in New Issue
Block a user