660 |
return(0); |
return(0); |
661 |
} |
} |
662 |
|
|
663 |
|
/* Check if PC register matches the compiled block virtual address */ |
664 |
|
static forced_inline int insn_block_match(cpu_mips_t *cpu,insn_block_t *block) |
665 |
|
{ |
666 |
|
m_uint64_t vpage; |
667 |
|
|
668 |
|
vpage = cpu->pc & ~(m_uint64_t)MIPS_MIN_PAGE_IMASK; |
669 |
|
return(block->start_pc == vpage); |
670 |
|
} |
671 |
|
|
672 |
/* Execute a compiled MIPS code */ |
/* Execute a compiled MIPS code */ |
673 |
void *insn_block_execute(cpu_mips_t *cpu) |
void *insn_block_execute(cpu_mips_t *cpu) |
674 |
{ |
{ |
675 |
pthread_t timer_irq_thread; |
pthread_t timer_irq_thread; |
676 |
insn_block_t *block; |
insn_block_t *block; |
677 |
m_uint32_t phys_page; |
m_uint32_t phys_page; |
|
int idle_count = 0; |
|
678 |
int timer_irq_check = 0; |
int timer_irq_check = 0; |
679 |
|
|
680 |
if (pthread_create(&timer_irq_thread,NULL, |
if (pthread_create(&timer_irq_thread,NULL, |
687 |
} |
} |
688 |
|
|
689 |
cpu->cpu_thread_running = TRUE; |
cpu->cpu_thread_running = TRUE; |
690 |
|
|
691 |
start_cpu: |
start_cpu: |
692 |
|
cpu->idle_count = 0; |
693 |
|
|
694 |
for(;;) { |
for(;;) { |
695 |
if (unlikely(!cpu->pc) || unlikely(cpu->state != MIPS_CPU_RUNNING)) |
if (unlikely(cpu->state != MIPS_CPU_RUNNING)) |
696 |
break; |
break; |
697 |
|
|
698 |
/* Handle virtual idle loop */ |
/* Handle virtual idle loop */ |
699 |
if (unlikely(cpu->pc == cpu->idle_pc)) { |
if (unlikely(cpu->pc == cpu->idle_pc)) { |
700 |
if (++idle_count == cpu->idle_max) { |
if (++cpu->idle_count == cpu->idle_max) { |
701 |
mips64_idle_loop(cpu); |
mips64_idle_loop(cpu); |
702 |
idle_count = 0; |
cpu->idle_count = 0; |
703 |
} |
} |
704 |
} |
} |
705 |
|
|
725 |
block = cpu->exec_phys_map[phys_page]; |
block = cpu->exec_phys_map[phys_page]; |
726 |
|
|
727 |
/* No block found, compile the page */ |
/* No block found, compile the page */ |
728 |
if (unlikely(!block)) { |
if (unlikely(!block) || unlikely(!insn_block_match(cpu,block))) |
729 |
|
{ |
730 |
|
if (block != NULL) { |
731 |
|
insn_block_free(cpu,block,TRUE); |
732 |
|
cpu->exec_phys_map[phys_page] = NULL; |
733 |
|
} |
734 |
|
|
735 |
block = insn_page_compile(cpu,cpu->pc); |
block = insn_page_compile(cpu,cpu->pc); |
736 |
if (unlikely(!block)) { |
if (unlikely(!block)) { |
737 |
fprintf(stderr, |
fprintf(stderr, |