mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-25 19:56:57 +00:00
cpu-exec: Move TB execution stuff out of cpu_exec()
Simplify cpu_exec() by extracting TB execution code outside of cpu_exec() into a new static inline function cpu_loop_exec_tb(). Backports commit 928de9ee14b0b63ee9f9275732ed3e1c8b5f4790 from qemu
This commit is contained in:
parent
d4ef96abf2
commit
aefb8935a9
|
@ -315,6 +315,39 @@ static inline void cpu_handle_interrupt(CPUState *cpu,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
|
||||||
|
TranslationBlock **last_tb, int *tb_exit)
|
||||||
|
{
|
||||||
|
uintptr_t ret;
|
||||||
|
|
||||||
|
if (unlikely(cpu->exit_request)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute the generated code */
|
||||||
|
ret = cpu_tb_exec(cpu, tb);
|
||||||
|
*last_tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK);
|
||||||
|
*tb_exit = ret & TB_EXIT_MASK;
|
||||||
|
switch (*tb_exit) {
|
||||||
|
case TB_EXIT_REQUESTED:
|
||||||
|
/* Something asked us to stop executing
|
||||||
|
* chained TBs; just continue round the main
|
||||||
|
* loop. Whatever requested the exit will also
|
||||||
|
* have set something else (eg exit_request or
|
||||||
|
* interrupt_request) which we will handle
|
||||||
|
* next time around the loop. But we need to
|
||||||
|
* ensure the tcg_exit_req read in generated code
|
||||||
|
* comes before the next read of cpu->exit_request
|
||||||
|
* or cpu->interrupt_request.
|
||||||
|
*/
|
||||||
|
smp_rmb();
|
||||||
|
*last_tb = NULL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* main execution loop */
|
/* main execution loop */
|
||||||
|
|
||||||
int cpu_exec(struct uc_struct *uc, CPUState *cpu)
|
int cpu_exec(struct uc_struct *uc, CPUState *cpu)
|
||||||
|
@ -325,8 +358,6 @@ int cpu_exec(struct uc_struct *uc, CPUState *cpu)
|
||||||
X86CPU *x86_cpu = X86_CPU(uc, cpu);
|
X86CPU *x86_cpu = X86_CPU(uc, cpu);
|
||||||
#endif
|
#endif
|
||||||
int ret;
|
int ret;
|
||||||
TranslationBlock *tb, *last_tb;
|
|
||||||
int tb_exit = 0;
|
|
||||||
|
|
||||||
if (cpu_handle_halt(cpu)) {
|
if (cpu_handle_halt(cpu)) {
|
||||||
return EXCP_HALTED;
|
return EXCP_HALTED;
|
||||||
|
@ -344,6 +375,9 @@ int cpu_exec(struct uc_struct *uc, CPUState *cpu)
|
||||||
env->invalid_error = UC_ERR_OK;
|
env->invalid_error = UC_ERR_OK;
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
TranslationBlock *tb, *last_tb;
|
||||||
|
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) {
|
||||||
|
@ -365,31 +399,7 @@ int cpu_exec(struct uc_struct *uc, CPUState *cpu)
|
||||||
ret = EXCP_HLT;
|
ret = EXCP_HLT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (likely(!cpu->exit_request)) {
|
cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit);
|
||||||
uintptr_t ret;
|
|
||||||
/* execute the generated code */
|
|
||||||
ret = cpu_tb_exec(cpu, tb);
|
|
||||||
last_tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK);
|
|
||||||
tb_exit = ret & TB_EXIT_MASK;
|
|
||||||
switch (tb_exit) {
|
|
||||||
case TB_EXIT_REQUESTED:
|
|
||||||
/* Something asked us to stop executing
|
|
||||||
* chained TBs; just continue round the main
|
|
||||||
* loop. Whatever requested the exit will also
|
|
||||||
* have set something else (eg exit_request or
|
|
||||||
* interrupt_request) which we will handle
|
|
||||||
* next time around the loop. But we need to
|
|
||||||
* ensure the tcg_exit_req read in generated code
|
|
||||||
* comes before the next read of cpu->exit_request
|
|
||||||
* or cpu->interrupt_request.
|
|
||||||
*/
|
|
||||||
smp_rmb();
|
|
||||||
last_tb = NULL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* for(;;) */
|
} /* for(;;) */
|
||||||
} else {
|
} else {
|
||||||
#if defined(__clang__) || !QEMU_GNUC_PREREQ(4, 6)
|
#if defined(__clang__) || !QEMU_GNUC_PREREQ(4, 6)
|
||||||
|
|
Loading…
Reference in a new issue