diff options
Diffstat (limited to 'cpu-exec.c')
-rw-r--r-- | cpu-exec.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/cpu-exec.c b/cpu-exec.c index f9ea080e31..9092145d0b 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -64,6 +64,12 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); cpu_pc_from_tb(env, tb); } + if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) { + /* We were asked to stop executing TBs (probably a pending + * interrupt. We've now stopped, so clear the flag. + */ + cpu->tcg_exit_req = 0; + } return next_tb; } @@ -608,7 +614,20 @@ int cpu_exec(CPUArchState *env) tc_ptr = tb->tc_ptr; /* execute the generated code */ next_tb = cpu_tb_exec(cpu, tc_ptr); - if ((next_tb & TB_EXIT_MASK) == TB_EXIT_ICOUNT_EXPIRED) { + switch (next_tb & TB_EXIT_MASK) { + 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. + */ + tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); + next_tb = 0; + break; + case TB_EXIT_ICOUNT_EXPIRED: + { /* Instruction counter expired. */ int insns_left; tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); @@ -632,6 +651,10 @@ int cpu_exec(CPUArchState *env) next_tb = 0; cpu_loop_exit(env); } + break; + } + default: + break; } } cpu->current_tb = NULL; |