mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-25 10:56:45 +00:00
cpu-exec: avoid repeated sigsetjmp on interrupts
The sigsetjmp only needs to be prepared once for the whole execution of cpu_exec. This patch takes care of the "== 0" side, using a nested loop so that cpu_handle_interrupt goes straight back to cpu_handle_exception without doing another sigsetjmp. Backports commit a42cf3f3f266a97ceb13e8b99bc7b13f7bf4192a from qemu
This commit is contained in:
parent
28b615a8b7
commit
af524401ad
|
@ -503,9 +503,6 @@ int cpu_exec(struct uc_struct *uc, CPUState *cpu)
|
||||||
env->invalid_error = UC_ERR_OK;
|
env->invalid_error = UC_ERR_OK;
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
TranslationBlock *last_tb = NULL;
|
|
||||||
int tb_exit = 0;
|
|
||||||
|
|
||||||
/* prepare setjmp context for exception handling */
|
/* prepare setjmp context for exception handling */
|
||||||
if (sigsetjmp(cpu->jmp_env, 0) == 0) {
|
if (sigsetjmp(cpu->jmp_env, 0) == 0) {
|
||||||
if (uc->stop_request || uc->invalid_error) {
|
if (uc->stop_request || uc->invalid_error) {
|
||||||
|
@ -513,21 +510,21 @@ int cpu_exec(struct uc_struct *uc, CPUState *cpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if an exception is pending, we execute it here */
|
/* if an exception is pending, we execute it here */
|
||||||
if (cpu_handle_exception(uc, cpu, &ret)) {
|
while (!cpu_handle_exception(uc, cpu, &ret)) {
|
||||||
break;
|
TranslationBlock *last_tb = NULL;
|
||||||
}
|
int tb_exit = 0;
|
||||||
|
|
||||||
last_tb = NULL; /* forget the last executed TB after exception */
|
while (!cpu_handle_interrupt(cpu, &last_tb)) {
|
||||||
atomic_mb_set(&cpu->tb_flushed, false); /* reset before first TB lookup */
|
TranslationBlock *tb = tb_find(cpu, last_tb, tb_exit);
|
||||||
while (!cpu_handle_interrupt(cpu, &last_tb)) {
|
if (!tb) { // invalid TB due to invalid code?
|
||||||
TranslationBlock *tb = tb_find(cpu, last_tb, tb_exit);
|
uc->invalid_error = UC_ERR_FETCH_UNMAPPED;
|
||||||
if (!tb) { // invalid TB due to invalid code?
|
ret = EXCP_HLT;
|
||||||
uc->invalid_error = UC_ERR_FETCH_UNMAPPED;
|
break;
|
||||||
ret = EXCP_HLT;
|
}
|
||||||
break;
|
cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit);
|
||||||
}
|
}
|
||||||
cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit);
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
#if defined(__clang__) || !QEMU_GNUC_PREREQ(4, 6)
|
#if defined(__clang__) || !QEMU_GNUC_PREREQ(4, 6)
|
||||||
/* Some compilers wrongly smash all local variables after
|
/* Some compilers wrongly smash all local variables after
|
||||||
|
|
Loading…
Reference in a new issue