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:
Sergey Fedorov 2018-02-24 00:14:29 -05:00 committed by Lioncash
parent d4ef96abf2
commit aefb8935a9
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -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 */
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);
#endif
int ret;
TranslationBlock *tb, *last_tb;
int tb_exit = 0;
if (cpu_handle_halt(cpu)) {
return EXCP_HALTED;
@ -344,6 +375,9 @@ int cpu_exec(struct uc_struct *uc, CPUState *cpu)
env->invalid_error = UC_ERR_OK;
for(;;) {
TranslationBlock *tb, *last_tb;
int tb_exit = 0;
/* prepare setjmp context for exception handling */
if (sigsetjmp(cpu->jmp_env, 0) == 0) {
if (uc->stop_request || uc->invalid_error) {
@ -365,31 +399,7 @@ int cpu_exec(struct uc_struct *uc, CPUState *cpu)
ret = EXCP_HLT;
break;
}
if (likely(!cpu->exit_request)) {
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;
}
}
cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit);
} /* for(;;) */
} else {
#if defined(__clang__) || !QEMU_GNUC_PREREQ(4, 6)