/[dynamips]/upstream/dynamips-0.2.7-RC2/ppc32_jit.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /upstream/dynamips-0.2.7-RC2/ppc32_jit.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

upstream/dynamips-0.2.7-RC1/ppc32_jit.c revision 7 by dpavlin, Sat Oct 6 16:23:47 2007 UTC upstream/dynamips-0.2.7-RC2/ppc32_jit.c revision 8 by dpavlin, Sat Oct 6 16:24:54 2007 UTC
# Line 53  void ppc32_jit_create_ilt(void) Line 53  void ppc32_jit_create_ilt(void)
53     for(i=0,count=0;ppc32_insn_tags[i].emit;i++)     for(i=0,count=0;ppc32_insn_tags[i].emit;i++)
54        count++;        count++;
55    
56     ilt = ilt_create(count+1,     ilt = ilt_create("ppc32j",count,
57                      (ilt_get_insn_cbk_t)ppc32_jit_get_insn,                      (ilt_get_insn_cbk_t)ppc32_jit_get_insn,
58                      (ilt_check_cbk_t)ppc32_jit_chk_lo,                      (ilt_check_cbk_t)ppc32_jit_chk_lo,
59                      (ilt_check_cbk_t)ppc32_jit_chk_hi);                      (ilt_check_cbk_t)ppc32_jit_chk_hi);
# Line 68  int ppc32_jit_init(cpu_ppc_t *cpu) Line 68  int ppc32_jit_init(cpu_ppc_t *cpu)
68     size_t len;     size_t len;
69     int i;     int i;
70    
71       /* JIT mapping for executable pages */
72       len = PPC_JIT_IA_HASH_SIZE * sizeof(void *);
73       cpu->exec_blk_map = m_memalign(4096,len);
74       memset(cpu->exec_blk_map,0,len);
75    
76     /* Physical mapping for executable pages */     /* Physical mapping for executable pages */
77     len = 1048576 * sizeof(void *);     len = PPC_JIT_PHYS_HASH_SIZE * sizeof(void *);
78     cpu->exec_phys_map = m_memalign(4096,len);     cpu->exec_phys_map = m_memalign(4096,len);
79     memset(cpu->exec_phys_map,0,len);     memset(cpu->exec_phys_map,0,len);
80    
# Line 122  int ppc32_jit_init(cpu_ppc_t *cpu) Line 127  int ppc32_jit_init(cpu_ppc_t *cpu)
127  u_int ppc32_jit_flush(cpu_ppc_t *cpu,u_int threshold)  u_int ppc32_jit_flush(cpu_ppc_t *cpu,u_int threshold)
128  {  {
129     ppc32_jit_tcb_t *p,*next;     ppc32_jit_tcb_t *p,*next;
130       m_uint32_t ia_hash;
131     u_int count = 0;     u_int count = 0;
132    
133     if (!threshold)     if (!threshold)
# Line 131  u_int ppc32_jit_flush(cpu_ppc_t *cpu,u_i Line 137  u_int ppc32_jit_flush(cpu_ppc_t *cpu,u_i
137        next = p->next;        next = p->next;
138    
139        if (p->acc_count <= threshold) {        if (p->acc_count <= threshold) {
140           cpu->exec_phys_map[p->phys_page] = NULL;           ia_hash = ppc32_jit_get_ia_hash(p->start_ia);
141           ppc32_jit_tcb_free(cpu,p,TRUE);           ppc32_jit_tcb_free(cpu,p,TRUE);
142    
143             if (cpu->exec_blk_map[ia_hash] == p)
144                cpu->exec_blk_map[ia_hash] = NULL;
145           count++;           count++;
146        }        }
147     }     }
# Line 162  void ppc32_jit_shutdown(cpu_ppc_t *cpu) Line 171  void ppc32_jit_shutdown(cpu_ppc_t *cpu)
171     /* Free the exec page array */     /* Free the exec page array */
172     free(cpu->exec_page_array);     free(cpu->exec_page_array);
173    
174       /* Free JIT block mapping */
175       free(cpu->exec_blk_map);  
176    
177     /* Free physical mapping for executable pages */     /* Free physical mapping for executable pages */
178     free(cpu->exec_phys_map);       free(cpu->exec_phys_map);
179  }  }
180    
181  /* Allocate an exec page */  /* Allocate an exec page */
# Line 362  static void ppc32_jit_tcb_free_patches(p Line 374  static void ppc32_jit_tcb_free_patches(p
374  }  }
375    
376  /* Adjust the JIT buffer if its size is not sufficient */  /* Adjust the JIT buffer if its size is not sufficient */
377  static int ppc32_jit_tcb_adjust_buffer(cpu_ppc_t *cpu,  static int ppc32_jit_tcb_adjust_buffer(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block)
                                        ppc32_jit_tcb_t *block)  
378  {  {
379     insn_exec_page_t *new_buffer;     insn_exec_page_t *new_buffer;
380    
# Line 427  void ppc32_jit_tcb_free(cpu_ppc_t *cpu,p Line 438  void ppc32_jit_tcb_free(cpu_ppc_t *cpu,p
438              block->prev->next = block->next;              block->prev->next = block->next;
439           else           else
440              cpu->tcb_list = block->next;              cpu->tcb_list = block->next;
441    
442             /* Remove the block from the physical mapping hash table */
443             if (block->phys_pprev) {
444                if (block->phys_next)
445                   block->phys_next->phys_pprev = block->phys_pprev;
446                
447                *(block->phys_pprev) = block->phys_next;
448                
449                block->phys_pprev = NULL;
450                block->phys_next = NULL;
451             }
452        }        }
453    
454        /* Free the patch tables */        /* Free the patch tables */
# Line 441  void ppc32_jit_tcb_free(cpu_ppc_t *cpu,p Line 463  void ppc32_jit_tcb_free(cpu_ppc_t *cpu,p
463    
464        /* Free the PowerPC-to-native code mapping */        /* Free the PowerPC-to-native code mapping */
465        free(block->jit_insn_ptr);        free(block->jit_insn_ptr);
466          
       /* Make the block return to the free list */  
467        block->next = cpu->tcb_free_list;        block->next = cpu->tcb_free_list;
468        cpu->tcb_free_list = block;        cpu->tcb_free_list = block;
469     }     }
# Line 452  void ppc32_jit_tcb_free(cpu_ppc_t *cpu,p Line 473  void ppc32_jit_tcb_free(cpu_ppc_t *cpu,p
473  static ppc32_jit_tcb_t *ppc32_jit_tcb_create(cpu_ppc_t *cpu,m_uint32_t vaddr)  static ppc32_jit_tcb_t *ppc32_jit_tcb_create(cpu_ppc_t *cpu,m_uint32_t vaddr)
474  {  {
475     ppc32_jit_tcb_t *block = NULL;     ppc32_jit_tcb_t *block = NULL;
476       m_uint32_t phys_page;
477    
478       if (unlikely(cpu->translate(cpu,cpu->ia,PPC32_MTS_ICACHE,&phys_page)))
479          return NULL;
480    
481     if (!(block = ppc32_jit_tcb_alloc(cpu)))     if (!(block = ppc32_jit_tcb_alloc(cpu)))
482        goto err_block_alloc;        goto err_block_alloc;
483    
484     block->start_ia = vaddr;     block->start_ia = vaddr;
485       block->phys_page = phys_page;
486       block->phys_hash = ppc32_jit_get_phys_hash(phys_page);  
487    
488     /* Allocate the first JIT buffer */     /* Allocate the first JIT buffer */
489     if (!(block->jit_buffer = exec_page_alloc(cpu)))     if (!(block->jit_buffer = exec_page_alloc(cpu)))
# Line 542  ppc32_jit_tcb_t *ppc32_jit_tcb_compile(c Line 569  ppc32_jit_tcb_t *ppc32_jit_tcb_compile(c
569    
570     cpu->tcb_list = block;     cpu->tcb_list = block;
571        
572       /* Add the block to the physical mapping hash table */
573       block->phys_next = cpu->exec_phys_map[block->phys_hash];
574       block->phys_pprev = &cpu->exec_phys_map[block->phys_hash];
575    
576       if (cpu->exec_phys_map[block->phys_hash] != NULL)
577          cpu->exec_phys_map[block->phys_hash]->phys_pprev = &block->phys_next;
578    
579       cpu->exec_phys_map[block->phys_hash] = block;
580    
581     cpu->compiled_pages++;     cpu->compiled_pages++;
582     return block;     return block;
583    
# Line 566  void ppc32_jit_tcb_run(cpu_ppc_t *cpu,pp Line 602  void ppc32_jit_tcb_run(cpu_ppc_t *cpu,pp
602     ppc32_jit_tcb_exec(cpu,block);     ppc32_jit_tcb_exec(cpu,block);
603  }  }
604    
 /* Check if the specified address belongs to the specified block */  
 int ppc32_jit_tcb_local_addr(ppc32_jit_tcb_t *block,m_uint32_t vaddr,  
                              u_char **jit_addr)  
 {  
    if ((vaddr >= block->start_ia) &&  
        ((vaddr - block->start_ia) < PPC32_MIN_PAGE_SIZE))  
    {  
       *jit_addr = ppc32_jit_tcb_get_host_ptr(block,vaddr);  
       return(1);  
    }  
   
    return(0);  
 }  
   
 /* Check if PC register matches the compiled block virtual address */  
 static forced_inline  
 int ppc32_jit_tcb_match(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block)  
 {  
    m_uint32_t vpage;  
   
    vpage = cpu->ia & ~PPC32_MIN_PAGE_IMASK;  
    return(block->start_ia == vpage);  
 }  
   
605  /* Execute compiled PowerPC code */  /* Execute compiled PowerPC code */
606  void *ppc32_jit_run_cpu(cpu_gen_t *gen)  void *ppc32_jit_run_cpu(cpu_gen_t *gen)
607  {      {    
608     cpu_ppc_t *cpu = CPU_PPC32(gen);     cpu_ppc_t *cpu = CPU_PPC32(gen);
609     pthread_t timer_irq_thread;     pthread_t timer_irq_thread;
610     ppc32_jit_tcb_t *block;     ppc32_jit_tcb_t *block;
611     m_uint32_t phys_page;     m_uint32_t ia_hash;
612     int timer_irq_check = 0;     int timer_irq_check = 0;
613    
614     if (pthread_create(&timer_irq_thread,NULL,     if (pthread_create(&timer_irq_thread,NULL,(void *)ppc32_timer_irq_run,cpu))
                       (void *)ppc32_timer_irq_run,cpu))  
615     {     {
616        fprintf(stderr,        fprintf(stderr,
617                "VM '%s': unable to create Timer IRQ thread for CPU%u.\n",                "VM '%s': unable to create Timer IRQ thread for CPU%u.\n",
# Line 629  void *ppc32_jit_run_cpu(cpu_gen_t *gen) Line 640  void *ppc32_jit_run_cpu(cpu_gen_t *gen)
640           }           }
641        }        }
642    
       /* Check IRQs */  
       if (unlikely(cpu->irq_check))  
          ppc32_trigger_irq(cpu);  
   
643        /* Handle the virtual CPU clock */        /* Handle the virtual CPU clock */
644        if (++timer_irq_check == cpu->timer_irq_check_itv) {        if (++timer_irq_check == cpu->timer_irq_check_itv) {
645           timer_irq_check = 0;           timer_irq_check = 0;
# Line 644  void *ppc32_jit_run_cpu(cpu_gen_t *gen) Line 651  void *ppc32_jit_run_cpu(cpu_gen_t *gen)
651              cpu->timer_irq_pending--;              cpu->timer_irq_pending--;
652    
653              vm_set_irq(cpu->vm,0);              vm_set_irq(cpu->vm,0);
             //ppc32_trigger_timer_irq(cpu);  
654           }           }
655        }        }
656    
657        /* Get the physical page address corresponding to PC register */        /* Check IRQs */
658        if (unlikely(cpu->translate(cpu,cpu->ia,PPC32_MTS_ICACHE,&phys_page))) {        if (unlikely(cpu->irq_check))
659           fprintf(stderr,"VM '%s': no physical page for CPU%u PC=0x%8.8xx\n",           ppc32_trigger_irq(cpu);
                  cpu->vm->name,gen->id,cpu->ia);  
          cpu_stop(gen);  
          break;  
       }  
660    
661        block = cpu->exec_phys_map[phys_page];        /* Get the JIT block corresponding to IA register */
662          ia_hash = ppc32_jit_get_ia_hash(cpu->ia);
663          block = cpu->exec_blk_map[ia_hash];
664    
665        /* No block found, compile the page */        /* No block found, compile the page */
666        if (unlikely(!block) || unlikely(!ppc32_jit_tcb_match(cpu,block)))        if (unlikely(!block) || unlikely(!ppc32_jit_tcb_match(cpu,block)))
667        {        {
668           if (block != NULL) {           if (block != NULL) {
669              ppc32_jit_tcb_free(cpu,block,TRUE);              ppc32_jit_tcb_free(cpu,block,TRUE);
670              cpu->exec_phys_map[phys_page] = NULL;              cpu->exec_blk_map[ia_hash] = NULL;
671           }           }
672    
673           block = ppc32_jit_tcb_compile(cpu,cpu->ia);           block = ppc32_jit_tcb_compile(cpu,cpu->ia);
674    
675           if (unlikely(!block)) {           if (unlikely(!block)) {
676              fprintf(stderr,              fprintf(stderr,
677                      "VM '%s': unable to compile block for CPU%u IA=0x%8.8x\n",                      "VM '%s': unable to compile block for CPU%u IA=0x%8.8x\n",
# Line 675  void *ppc32_jit_run_cpu(cpu_gen_t *gen) Line 680  void *ppc32_jit_run_cpu(cpu_gen_t *gen)
680              break;              break;
681           }           }
682    
683           block->phys_page = phys_page;           cpu->exec_blk_map[ia_hash] = block;
          cpu->exec_phys_map[phys_page] = block;  
684        }        }
685    
686  #if DEBUG_BLOCK_TIMESTAMP  #if DEBUG_BLOCK_TIMESTAMP

Legend:
Removed from v.7  
changed lines
  Added in v.8

  ViewVC Help
Powered by ViewVC 1.1.26