diff --git a/cpu-i386.h b/cpu-i386.h index abbb037235..6c7afbf6e2 100644 --- a/cpu-i386.h +++ b/cpu-i386.h @@ -251,7 +251,7 @@ typedef struct CPUX86State { int error_code; int exception_is_int; int exception_next_eip; - + struct TranslationBlock *current_tb; /* currently executing TB */ uint32_t cr[5]; /* NOTE: cr1 is unused */ uint32_t dr[8]; /* debug registers */ int interrupt_request; /* if true, will exit from cpu_exec() ASAP */ @@ -259,7 +259,7 @@ typedef struct CPUX86State { request interrupt number */ int hard_interrupt_request; int user_mode_only; /* user mode only simulation */ - + /* user data */ void *opaque; } CPUX86State; @@ -295,7 +295,6 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, /* MMU defines */ void cpu_x86_init_mmu(CPUX86State *env); -extern CPUX86State *global_env; extern int phys_ram_size; extern int phys_ram_fd; extern uint8_t *phys_ram_base; diff --git a/exec.c b/exec.c index 636fe25b80..4de0c60f1a 100644 --- a/exec.c +++ b/exec.c @@ -26,7 +26,13 @@ #include #include +#include "config.h" +#ifdef TARGET_I386 #include "cpu-i386.h" +#endif +#ifdef TARGET_ARM +#include "cpu-arm.h" +#endif #include "exec.h" //#define DEBUG_TB_INVALIDATE @@ -564,6 +570,67 @@ TranslationBlock *tb_find_pc(unsigned long tc_ptr) return &tbs[m_max]; } +static void tb_reset_jump_recursive(TranslationBlock *tb); + +static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n) +{ + TranslationBlock *tb1, *tb_next, **ptb; + unsigned int n1; + + tb1 = tb->jmp_next[n]; + if (tb1 != NULL) { + /* find head of list */ + for(;;) { + n1 = (long)tb1 & 3; + tb1 = (TranslationBlock *)((long)tb1 & ~3); + if (n1 == 2) + break; + tb1 = tb1->jmp_next[n1]; + } + /* we are now sure now that tb jumps to tb1 */ + tb_next = tb1; + + /* remove tb from the jmp_first list */ + ptb = &tb_next->jmp_first; + for(;;) { + tb1 = *ptb; + n1 = (long)tb1 & 3; + tb1 = (TranslationBlock *)((long)tb1 & ~3); + if (n1 == n && tb1 == tb) + break; + ptb = &tb1->jmp_next[n1]; + } + *ptb = tb->jmp_next[n]; + tb->jmp_next[n] = NULL; + + /* suppress the jump to next tb in generated code */ + tb_reset_jump(tb, n); + + /* suppress jumps in the tb on which we could have jump */ + tb_reset_jump_recursive(tb_next); + } +} + +static void tb_reset_jump_recursive(TranslationBlock *tb) +{ + tb_reset_jump_recursive2(tb, 0); + tb_reset_jump_recursive2(tb, 1); +} + +void cpu_interrupt(CPUState *env) +{ + TranslationBlock *tb; + + env->interrupt_request = 1; + /* if the cpu is currently executing code, we must unlink it and + all the potentially executing TB */ + tb = env->current_tb; + if (tb) { + tb_reset_jump_recursive(tb); + } +} + + void cpu_abort(CPUState *env, const char *fmt, ...) { va_list ap;