--- upstream/dynamips-0.2.5/mips64_jit.c 2007/10/06 16:01:44 1 +++ upstream/dynamips-0.2.6-RC3/mips64_jit.c 2007/10/06 16:06:49 4 @@ -660,35 +660,47 @@ return(0); } +/* Check if PC register matches the compiled block virtual address */ +static forced_inline int insn_block_match(cpu_mips_t *cpu,insn_block_t *block) +{ + m_uint64_t vpage; + + vpage = cpu->pc & ~(m_uint64_t)MIPS_MIN_PAGE_IMASK; + return(block->start_pc == vpage); +} + /* Execute a compiled MIPS code */ void *insn_block_execute(cpu_mips_t *cpu) { pthread_t timer_irq_thread; insn_block_t *block; m_uint32_t phys_page; - int idle_count = 0; int timer_irq_check = 0; if (pthread_create(&timer_irq_thread,NULL, (void *)mips64_timer_irq_run,cpu)) { - fprintf(stderr,"VM '%s': unable to create Timer IRQ thread for CPU%u.\n", + fprintf(stderr, + "VM '%s': unable to create Timer IRQ thread for CPU%u.\n", cpu->vm->name,cpu->id); cpu_stop(cpu); return NULL; } cpu->cpu_thread_running = TRUE; + start_cpu: + cpu->idle_count = 0; + for(;;) { - if (unlikely(!cpu->pc) || unlikely(cpu->state != MIPS_CPU_RUNNING)) + if (unlikely(cpu->state != MIPS_CPU_RUNNING)) break; /* Handle virtual idle loop */ if (unlikely(cpu->pc == cpu->idle_pc)) { - if (++idle_count == cpu->idle_max) { + if (++cpu->idle_count == cpu->idle_max) { mips64_idle_loop(cpu); - idle_count = 0; + cpu->idle_count = 0; } } @@ -714,7 +726,13 @@ block = cpu->exec_phys_map[phys_page]; /* No block found, compile the page */ - if (unlikely(!block)) { + if (unlikely(!block) || unlikely(!insn_block_match(cpu,block))) + { + if (block != NULL) { + insn_block_free(cpu,block,TRUE); + cpu->exec_phys_map[phys_page] = NULL; + } + block = insn_page_compile(cpu,cpu->pc); if (unlikely(!block)) { fprintf(stderr,