/[dynamips]/upstream/dynamips-0.2.7-RC2/mips64_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/mips64_jit.c

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

upstream/dynamips-0.2.7-RC1/mips64_jit.c revision 7 by dpavlin, Sat Oct 6 16:23:47 2007 UTC upstream/dynamips-0.2.7-RC2/mips64_jit.c revision 8 by dpavlin, Sat Oct 6 16:24:54 2007 UTC
# Line 16  Line 16 
16  #include <fcntl.h>  #include <fcntl.h>
17  #include <assert.h>  #include <assert.h>
18    
19    #include "sbox.h"
20  #include "cpu.h"  #include "cpu.h"
21  #include "device.h"  #include "device.h"
22  #include "mips64.h"  #include "mips64.h"
# Line 82  void mips64_jit_create_ilt(void) Line 83  void mips64_jit_create_ilt(void)
83     for(i=0,count=0;mips64_insn_tags[i].emit;i++)     for(i=0,count=0;mips64_insn_tags[i].emit;i++)
84        count++;        count++;
85    
86     ilt = ilt_create(count+1,     ilt = ilt_create("mips64j",count,
87                      (ilt_get_insn_cbk_t)mips64_jit_get_insn,                      (ilt_get_insn_cbk_t)mips64_jit_get_insn,
88                      (ilt_check_cbk_t)mips64_jit_chk_lo,                      (ilt_check_cbk_t)mips64_jit_chk_lo,
89                      (ilt_check_cbk_t)mips64_jit_chk_hi);                      (ilt_check_cbk_t)mips64_jit_chk_hi);
# Line 98  int mips64_jit_init(cpu_mips_t *cpu) Line 99  int mips64_jit_init(cpu_mips_t *cpu)
99     int i;     int i;
100    
101     /* Physical mapping for executable pages */     /* Physical mapping for executable pages */
102     len = 1048576 * sizeof(void *);     len = MIPS_JIT_PC_HASH_SIZE * sizeof(void *);
103     cpu->exec_phys_map = m_memalign(4096,len);     cpu->exec_blk_map = m_memalign(4096,len);
104     memset(cpu->exec_phys_map,0,len);     memset(cpu->exec_blk_map,0,len);
105    
106     /* Get area size */     /* Get area size */
107     if (!(area_size = cpu->vm->exec_area_size))     if (!(area_size = cpu->vm->exec_area_size))
# Line 151  int mips64_jit_init(cpu_mips_t *cpu) Line 152  int mips64_jit_init(cpu_mips_t *cpu)
152  u_int mips64_jit_flush(cpu_mips_t *cpu,u_int threshold)  u_int mips64_jit_flush(cpu_mips_t *cpu,u_int threshold)
153  {  {
154     mips64_jit_tcb_t *p,*next;     mips64_jit_tcb_t *p,*next;
155       m_uint32_t pc_hash;
156     u_int count = 0;     u_int count = 0;
157    
158     if (!threshold)     if (!threshold)
# Line 160  u_int mips64_jit_flush(cpu_mips_t *cpu,u Line 162  u_int mips64_jit_flush(cpu_mips_t *cpu,u
162        next = p->next;        next = p->next;
163    
164        if (p->acc_count <= threshold) {        if (p->acc_count <= threshold) {
165           cpu->exec_phys_map[p->phys_page] = NULL;           pc_hash = mips64_jit_get_pc_hash(p->start_pc);
166             cpu->exec_blk_map[pc_hash] = NULL;
167           mips64_jit_tcb_free(cpu,p,TRUE);           mips64_jit_tcb_free(cpu,p,TRUE);
168           count++;           count++;
169        }        }
# Line 192  void mips64_jit_shutdown(cpu_mips_t *cpu Line 195  void mips64_jit_shutdown(cpu_mips_t *cpu
195     free(cpu->exec_page_array);     free(cpu->exec_page_array);
196    
197     /* Free physical mapping for executable pages */     /* Free physical mapping for executable pages */
198     free(cpu->exec_phys_map);       free(cpu->exec_blk_map);  
199  }  }
200    
201  /* Allocate an exec page */  /* Allocate an exec page */
# Line 318  static inline void *physmem_get_hptr(vm_ Line 321  static inline void *physmem_get_hptr(vm_
321     return(dev->handler(vm->boot_cpu,dev,offset,op_size,op_type,data));     return(dev->handler(vm->boot_cpu,dev,offset,op_size,op_type,data));
322  }  }
323    
324    /* Check if an instruction is in a delay slot or not */
325    int mips64_jit_is_delay_slot(mips64_jit_tcb_t *b,m_uint64_t pc)
326    {  
327       struct mips64_insn_tag *tag;
328       m_uint32_t offset,insn;
329    
330       offset = (pc - b->start_pc) >> 2;
331    
332       if (!offset)
333          return(FALSE);
334    
335       /* Fetch the previous instruction to determine if it is a jump */
336       insn = vmtoh32(b->mips_code[offset-1]);
337       tag = insn_tag_find(insn);
338       assert(tag != NULL);
339       return(!tag->delay_slot);
340    }
341    
342  /* Fetch a MIPS instruction and emit corresponding translated code */  /* Fetch a MIPS instruction and emit corresponding translated code */
343  struct mips64_insn_tag *mips64_jit_fetch_and_emit(cpu_mips_t *cpu,  struct mips64_insn_tag *mips64_jit_fetch_and_emit(cpu_mips_t *cpu,
344                                                    mips64_jit_tcb_t *block,                                                    mips64_jit_tcb_t *block,
# Line 696  void mips64_jit_tcb_run(cpu_mips_t *cpu, Line 717  void mips64_jit_tcb_run(cpu_mips_t *cpu,
717  #endif  #endif
718  }  }
719    
 /* Check if the specified address belongs to the specified block */  
 int mips64_jit_tcb_local_addr(mips64_jit_tcb_t *block,m_uint64_t vaddr,  
                               u_char **jit_addr)  
 {  
    if ((vaddr >= block->start_pc) &&  
        ((vaddr - block->start_pc) < MIPS_MIN_PAGE_SIZE))  
    {  
       *jit_addr = mips64_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 mips64_jit_tcb_match(cpu_mips_t *cpu,mips64_jit_tcb_t *block)  
 {  
    m_uint64_t vpage;  
   
    vpage = cpu->pc & ~(m_uint64_t)MIPS_MIN_PAGE_IMASK;  
    return(block->start_pc == vpage);  
 }  
   
720  /* Execute compiled MIPS code */  /* Execute compiled MIPS code */
721  void *mips64_jit_run_cpu(cpu_gen_t *gen)  void *mips64_jit_run_cpu(cpu_gen_t *gen)
722  {      {    
723     cpu_mips_t *cpu = CPU_MIPS64(gen);     cpu_mips_t *cpu = CPU_MIPS64(gen);
724     pthread_t timer_irq_thread;     pthread_t timer_irq_thread;
725     mips64_jit_tcb_t *block;     mips64_jit_tcb_t *block;
    m_uint32_t phys_page;  
726     int timer_irq_check = 0;     int timer_irq_check = 0;
727       m_uint32_t pc_hash;
728    
729     if (pthread_create(&timer_irq_thread,NULL,     if (pthread_create(&timer_irq_thread,NULL,
730                        (void *)mips64_timer_irq_run,cpu))                        (void *)mips64_timer_irq_run,cpu))
# Line 740  void *mips64_jit_run_cpu(cpu_gen_t *gen) Line 737  void *mips64_jit_run_cpu(cpu_gen_t *gen)
737     }     }
738    
739     gen->cpu_thread_running = TRUE;     gen->cpu_thread_running = TRUE;
   
740   start_cpu:     start_cpu:  
741     gen->idle_count = 0;     gen->idle_count = 0;
742    
# Line 770  void *mips64_jit_run_cpu(cpu_gen_t *gen) Line 766  void *mips64_jit_run_cpu(cpu_gen_t *gen)
766           }           }
767        }        }
768    
769        /* Get the physical page address corresponding to PC register */        pc_hash = mips64_jit_get_pc_hash(cpu->pc);
770        if (unlikely(cpu->translate(cpu,cpu->pc,&phys_page))) {        block = cpu->exec_blk_map[pc_hash];
          fprintf(stderr,"VM '%s': no physical page for CPU%u PC=0x%llx\n",  
                  cpu->vm->name,gen->id,cpu->pc);  
          cpu_stop(gen);  
          break;  
       }  
   
       block = cpu->exec_phys_map[phys_page];  
771    
772        /* No block found, compile the page */        /* No block found, compile the page */
773        if (unlikely(!block) || unlikely(!mips64_jit_tcb_match(cpu,block)))        if (unlikely(!block) || unlikely(!mips64_jit_tcb_match(cpu,block)))
774        {        {        
775           if (block != NULL) {           if (block != NULL) {
776              mips64_jit_tcb_free(cpu,block,TRUE);              mips64_jit_tcb_free(cpu,block,TRUE);
777              cpu->exec_phys_map[phys_page] = NULL;              cpu->exec_blk_map[pc_hash] = NULL;
778           }           }
779    
780           block = mips64_jit_tcb_compile(cpu,cpu->pc);           block = mips64_jit_tcb_compile(cpu,cpu->pc);
# Line 797  void *mips64_jit_run_cpu(cpu_gen_t *gen) Line 786  void *mips64_jit_run_cpu(cpu_gen_t *gen)
786              break;              break;
787           }           }
788    
789           block->phys_page = phys_page;           cpu->exec_blk_map[pc_hash] = block;
          cpu->exec_phys_map[phys_page] = block;  
790        }        }
791    
792  #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