diff options
author | Sergey Fedorov <serge.fdrv@gmail.com> | 2016-05-11 13:21:48 +0300 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2016-05-12 14:06:42 -1000 |
commit | ea284766ec6b9f1712369249566b4c372f3cec8b (patch) | |
tree | 9dc6aceb0e1120266a0fc322f20d80d3aa75ff9e | |
parent | 8b2d34e997371c9729a0f41e3cc624d4300bbe78 (diff) |
cpu-exec: Move exception handling out of cpu_exec()
Simplify cpu_exec() by extracting exception handling code out of
cpu_exec() into a new static inline function cpu_handle_exception().
Also make cpu_handle_debug_exception() inline as it is used only once.
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Message-Id: <1462962111-32237-3-git-send-email-sergey.fedorov@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
-rw-r--r-- | cpu-exec.c | 93 |
1 files changed, 52 insertions, 41 deletions
diff --git a/cpu-exec.c b/cpu-exec.c index 529cac2213..36df39543b 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -374,7 +374,7 @@ static inline bool cpu_handle_halt(CPUState *cpu) return false; } -static void cpu_handle_debug_exception(CPUState *cpu) +static inline void cpu_handle_debug_exception(CPUState *cpu) { CPUClass *cc = CPU_GET_CLASS(cpu); CPUWatchpoint *wp; @@ -388,6 +388,55 @@ static void cpu_handle_debug_exception(CPUState *cpu) cc->debug_excp_handler(cpu); } +static inline bool cpu_handle_exception(CPUState *cpu, int *ret) +{ + if (cpu->exception_index >= 0) { + if (cpu->exception_index >= EXCP_INTERRUPT) { + /* exit request from the cpu execution loop */ + *ret = cpu->exception_index; + if (*ret == EXCP_DEBUG) { + cpu_handle_debug_exception(cpu); + } + cpu->exception_index = -1; + return true; + } else { +#if defined(CONFIG_USER_ONLY) + /* if user mode only, we simulate a fake exception + which will be handled outside the cpu execution + loop */ +#if defined(TARGET_I386) + CPUClass *cc = CPU_GET_CLASS(cpu); + cc->do_interrupt(cpu); +#endif + *ret = cpu->exception_index; + cpu->exception_index = -1; + return true; +#else + if (replay_exception()) { + CPUClass *cc = CPU_GET_CLASS(cpu); + cc->do_interrupt(cpu); + cpu->exception_index = -1; + } else if (!replay_has_interrupt()) { + /* give a chance to iothread in replay mode */ + *ret = EXCP_INTERRUPT; + return true; + } +#endif + } +#ifndef CONFIG_USER_ONLY + } else if (replay_has_exception() + && cpu->icount_decr.u16.low + cpu->icount_extra == 0) { + /* try to cause an exception pending in the log */ + TranslationBlock *last_tb = NULL; /* Avoid chaining TBs */ + cpu_exec_nocache(cpu, 1, tb_find_fast(cpu, &last_tb, 0), true); + *ret = -1; + return true; +#endif + } + + return false; +} + /* main execution loop */ int cpu_exec(CPUState *cpu) @@ -425,50 +474,12 @@ int cpu_exec(CPUState *cpu) */ init_delay_params(&sc, cpu); - /* prepare setjmp context for exception handling */ for(;;) { + /* prepare setjmp context for exception handling */ if (sigsetjmp(cpu->jmp_env, 0) == 0) { /* if an exception is pending, we execute it here */ - if (cpu->exception_index >= 0) { - if (cpu->exception_index >= EXCP_INTERRUPT) { - /* exit request from the cpu execution loop */ - ret = cpu->exception_index; - if (ret == EXCP_DEBUG) { - cpu_handle_debug_exception(cpu); - } - cpu->exception_index = -1; - break; - } else { -#if defined(CONFIG_USER_ONLY) - /* if user mode only, we simulate a fake exception - which will be handled outside the cpu execution - loop */ -#if defined(TARGET_I386) - cc->do_interrupt(cpu); -#endif - ret = cpu->exception_index; - cpu->exception_index = -1; - break; -#else - if (replay_exception()) { - cc->do_interrupt(cpu); - cpu->exception_index = -1; - } else if (!replay_has_interrupt()) { - /* give a chance to iothread in replay mode */ - ret = EXCP_INTERRUPT; - break; - } -#endif - } -#ifndef CONFIG_USER_ONLY - } else if (replay_has_exception() - && cpu->icount_decr.u16.low + cpu->icount_extra == 0) { - /* try to cause an exception pending in the log */ - last_tb = NULL; /* Avoid chaining TBs */ - cpu_exec_nocache(cpu, 1, tb_find_fast(cpu, &last_tb, 0), true); - ret = -1; + if (cpu_handle_exception(cpu, &ret)) { break; -#endif } last_tb = NULL; /* forget the last executed TB after exception */ |