/[dynamips]/trunk/mips64_exec.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 /trunk/mips64_exec.c

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

upstream/dynamips-0.2.6-RC4/mips64_exec.c revision 5 by dpavlin, Sat Oct 6 16:08:03 2007 UTC upstream/dynamips-0.2.7-RC3/mips64_exec.c revision 9 by dpavlin, Sat Oct 6 16:26:06 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   * Cisco 7200 (Predator) simulation platform.   * Cisco router simulation platform.
3   * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)   * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4   *   *
5   * MIPS64 Step-by-step execution.   * MIPS64 Step-by-step execution.
# Line 16  Line 16 
16  #include <sys/mman.h>  #include <sys/mman.h>
17  #include <fcntl.h>  #include <fcntl.h>
18    
 #include "rbtree.h"  
 #include "mips64.h"  
 #include "dynamips.h"  
 #include "vm.h"  
 #include "memory.h"  
19  #include "cpu.h"  #include "cpu.h"
20  #include "cp0.h"  #include "vm.h"
21  #include "mips64_exec.h"  #include "mips64_exec.h"
22    #include "memory.h"
23  #include "insn_lookup.h"  #include "insn_lookup.h"
24    #include "dynamips.h"
25    
26  /* Forward declaration of instruction array */  /* Forward declaration of instruction array */
27  static struct insn_exec_tag mips64_exec_tags[];  static struct mips64_insn_exec_tag mips64_exec_tags[];
28  static insn_lookup_t *ilt = NULL;  static insn_lookup_t *ilt = NULL;
29    
30  /* ILT */  /* ILT */
# Line 36  static forced_inline void *mips64_exec_g Line 33  static forced_inline void *mips64_exec_g
33     return(&mips64_exec_tags[index]);     return(&mips64_exec_tags[index]);
34  }  }
35    
36  static int mips64_exec_chk_lo(struct insn_exec_tag *tag,int value)  static int mips64_exec_chk_lo(struct mips64_insn_exec_tag *tag,int value)
37  {  {
38     return((value & tag->mask) == (tag->value & 0xFFFF));     return((value & tag->mask) == (tag->value & 0xFFFF));
39  }  }
40    
41  static int mips64_exec_chk_hi(struct insn_exec_tag *tag,int value)  static int mips64_exec_chk_hi(struct mips64_insn_exec_tag *tag,int value)
42  {  {
43     return((value & (tag->mask >> 16)) == (tag->value >> 16));     return((value & (tag->mask >> 16)) == (tag->value >> 16));
44  }  }
# Line 54  void mips64_exec_create_ilt(void) Line 51  void mips64_exec_create_ilt(void)
51     for(i=0,count=0;mips64_exec_tags[i].exec;i++)     for(i=0,count=0;mips64_exec_tags[i].exec;i++)
52        count++;        count++;
53    
54     ilt = ilt_create(count,     ilt = ilt_create("mips64e",count,
55                      (ilt_get_insn_cbk_t)mips64_exec_get_insn,                      (ilt_get_insn_cbk_t)mips64_exec_get_insn,
56                      (ilt_check_cbk_t)mips64_exec_chk_lo,                      (ilt_check_cbk_t)mips64_exec_chk_lo,
57                      (ilt_check_cbk_t)mips64_exec_chk_hi);                      (ilt_check_cbk_t)mips64_exec_chk_hi);
# Line 84  int mips64_dump_insn(char *buffer,size_t Line 81  int mips64_dump_insn(char *buffer,size_t
81  {  {
82     char insn_name[64],insn_format[32],*name;     char insn_name[64],insn_format[32],*name;
83     int base,rs,rd,rt,sa,offset,imm;     int base,rs,rd,rt,sa,offset,imm;
84     struct insn_exec_tag *tag;     struct mips64_insn_exec_tag *tag;
85     m_uint64_t new_pc;     m_uint64_t new_pc;
86     int index;     int index;
87    
# Line 325  static forced_inline int mips64_exec_fet Line 322  static forced_inline int mips64_exec_fet
322     return(0);     return(0);
323  }  }
324    
325    /* Unknown opcode */
326    static fastcall int mips64_exec_unknown(cpu_mips_t *cpu,mips_insn_t insn)
327    {
328       printf("MIPS64: unknown opcode 0x%8.8x at pc = 0x%llx\n",insn,cpu->pc);
329       mips64_dump_regs(cpu->gen);
330       return(0);
331    }
332    
333  /* Execute a single instruction */  /* Execute a single instruction */
334  static forced_inline int  static forced_inline int
335  mips64_exec_single_instruction(cpu_mips_t *cpu,mips_insn_t instruction)  mips64_exec_single_instruction(cpu_mips_t *cpu,mips_insn_t instruction)
336  {  {
337     register fastcall int (*exec)(cpu_mips_t *,mips_insn_t) = NULL;     register fastcall int (*exec)(cpu_mips_t *,mips_insn_t) = NULL;
338     struct insn_exec_tag *tag;     struct mips64_insn_exec_tag *tag;
339     int index;     int index;
340    
341  #if DEBUG_PERF_COUNTER  #if DEBUG_INSN_PERF_CNT
342     cpu->perf_counter++;     cpu->perf_counter++;
343  #endif  #endif
344        
# Line 345  mips64_exec_single_instruction(cpu_mips_ Line 350  mips64_exec_single_instruction(cpu_mips_
350     tag = mips64_exec_get_insn(index);     tag = mips64_exec_get_insn(index);
351     exec = tag->exec;     exec = tag->exec;
352    
    if (likely(exec != NULL)) {  
353  #if NJM_STATS_ENABLE  #if NJM_STATS_ENABLE
354        cpu->insn_exec_count++;     cpu->insn_exec_count++;
355        mips64_exec_tags[index].count++;     mips64_exec_tags[index].count++;
356  #endif  #endif
357  #if 0  #if 0
358     {     {
# Line 359  mips64_exec_single_instruction(cpu_mips_ Line 363  mips64_exec_single_instruction(cpu_mips_
363     }     }
364  #endif  #endif
365    
366        return(exec(cpu,instruction));     return(exec(cpu,instruction));
    }  
   
    printf("MIPS64: unknown opcode 0x%8.8x at pc = 0x%llx\n",  
           instruction,cpu->pc);  
    mips64_dump_regs(cpu);  
    return(0);  
367  }  }
368    
369  /* Single-step execution */  /* Single-step execution */
370  void mips64_exec_single_step(cpu_mips_t *cpu,mips_insn_t instruction)  fastcall void mips64_exec_single_step(cpu_mips_t *cpu,mips_insn_t instruction)
371  {  {
372     int res;     int res;
373    
# Line 380  void mips64_exec_single_step(cpu_mips_t Line 378  void mips64_exec_single_step(cpu_mips_t
378  }  }
379    
380  /* Run MIPS code in step-by-step mode */  /* Run MIPS code in step-by-step mode */
381  void *mips64_exec_run_cpu(cpu_mips_t *cpu)  void *mips64_exec_run_cpu(cpu_gen_t *gen)
382  {    {  
383       cpu_mips_t *cpu = CPU_MIPS64(gen);
384     pthread_t timer_irq_thread;     pthread_t timer_irq_thread;
    mips_insn_t insn;  
385     int timer_irq_check = 0;     int timer_irq_check = 0;
386       mips_insn_t insn;
387     int res;     int res;
388    
389     if (pthread_create(&timer_irq_thread,NULL,     if (pthread_create(&timer_irq_thread,NULL,
390                        (void *)mips64_timer_irq_run,cpu))                        (void *)mips64_timer_irq_run,cpu))
391     {     {
392        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",
393                cpu->vm->name,cpu->id);                cpu->vm->name,gen->id);
394        cpu_stop(cpu);        cpu_stop(gen);
395        return NULL;        return NULL;
396     }     }
397    
398     cpu->cpu_thread_running = TRUE;     gen->cpu_thread_running = TRUE;
399    
400   start_cpu:   start_cpu:
401     cpu->idle_count = 0;     gen->idle_count = 0;
402    
403     for(;;) {     for(;;) {
404        if (unlikely(cpu->state != MIPS_CPU_RUNNING))        if (unlikely(gen->state != CPU_STATE_RUNNING))
405           break;           break;
406    
407        /* Handle virtual idle loop */        /* Handle virtual idle loop */
408        if (unlikely(cpu->pc == cpu->idle_pc)) {        if (unlikely(cpu->pc == cpu->idle_pc)) {
409           if (++cpu->idle_count == cpu->idle_max) {           if (++gen->idle_count == gen->idle_max) {
410              mips64_idle_loop(cpu);              cpu_idle_loop(gen);
411              cpu->idle_count = 0;              gen->idle_count = 0;
412           }           }
413        }        }
414    
# Line 438  void *mips64_exec_run_cpu(cpu_mips_t *cp Line 437  void *mips64_exec_run_cpu(cpu_mips_t *cp
437        res = mips64_exec_single_instruction(cpu,insn);        res = mips64_exec_single_instruction(cpu,insn);
438    
439        /* Normal flow ? */        /* Normal flow ? */
440        if (likely(!res)) cpu->pc += 4;        if (likely(!res)) cpu->pc += sizeof(mips_insn_t);
441     }     }
442    
443     if (!cpu->pc) {     if (!cpu->pc) {
444        cpu_stop(cpu);        cpu_stop(gen);
445        cpu_log(cpu,"SLOW_EXEC","PC=0, halting CPU.\n");        cpu_log(gen,"SLOW_EXEC","PC=0, halting CPU.\n");
446     }     }
447    
448     /* Check regularly if the CPU has been restarted */     /* Check regularly if the CPU has been restarted */
449     while(cpu->cpu_thread_running) {     while(gen->cpu_thread_running) {
450        cpu->seq_state++;        gen->seq_state++;
451    
452        switch(cpu->state) {        switch(gen->state) {
453           case MIPS_CPU_RUNNING:           case CPU_STATE_RUNNING:
454              cpu->state = MIPS_CPU_RUNNING;              gen->state = CPU_STATE_RUNNING;
455              goto start_cpu;              goto start_cpu;
456    
457           case MIPS_CPU_HALTED:               case CPU_STATE_HALTED:    
458              cpu->cpu_thread_running = FALSE;              gen->cpu_thread_running = FALSE;
459              pthread_join(timer_irq_thread,NULL);              pthread_join(timer_irq_thread,NULL);
460              break;              break;
461        }        }
# Line 1086  static fastcall int mips64_exec_CFC0(cpu Line 1085  static fastcall int mips64_exec_CFC0(cpu
1085     int rt = bits(insn,16,20);     int rt = bits(insn,16,20);
1086     int rd = bits(insn,11,15);     int rd = bits(insn,11,15);
1087    
1088     cp0_exec_cfc0(cpu,rt,rd);     mips64_cp0_exec_cfc0(cpu,rt,rd);
1089     return(0);     return(0);
1090  }  }
1091    
# Line 1096  static fastcall int mips64_exec_CTC0(cpu Line 1095  static fastcall int mips64_exec_CTC0(cpu
1095     int rt = bits(insn,16,20);     int rt = bits(insn,16,20);
1096     int rd = bits(insn,11,15);     int rd = bits(insn,11,15);
1097    
1098     cp0_exec_ctc0(cpu,rt,rd);     mips64_cp0_exec_ctc0(cpu,rt,rd);
1099     return(0);     return(0);
1100  }  }
1101    
# Line 1160  static fastcall int mips64_exec_DMFC0(cp Line 1159  static fastcall int mips64_exec_DMFC0(cp
1159     int rt = bits(insn,16,20);     int rt = bits(insn,16,20);
1160     int rd = bits(insn,11,15);     int rd = bits(insn,11,15);
1161    
1162     cp0_exec_dmfc0(cpu,rt,rd);     mips64_cp0_exec_dmfc0(cpu,rt,rd);
1163     return(0);     return(0);
1164  }  }
1165    
# Line 1180  static fastcall int mips64_exec_DMTC0(cp Line 1179  static fastcall int mips64_exec_DMTC0(cp
1179     int rt = bits(insn,16,20);     int rt = bits(insn,16,20);
1180     int rd = bits(insn,11,15);     int rd = bits(insn,11,15);
1181    
1182     cp0_exec_dmtc0(cpu,rt,rd);     mips64_cp0_exec_dmtc0(cpu,rt,rd);
1183     return(0);     return(0);
1184  }  }
1185    
# Line 1544  static fastcall int mips64_exec_MFC0(cpu Line 1543  static fastcall int mips64_exec_MFC0(cpu
1543     int rt = bits(insn,16,20);     int rt = bits(insn,16,20);
1544     int rd = bits(insn,11,15);     int rd = bits(insn,11,15);
1545    
1546     cp0_exec_mfc0(cpu,rt,rd);     mips64_cp0_exec_mfc0(cpu,rt,rd);
1547     return(0);     return(0);
1548  }  }
1549    
# Line 1592  static fastcall int mips64_exec_MTC0(cpu Line 1591  static fastcall int mips64_exec_MTC0(cpu
1591     int rt = bits(insn,16,20);     int rt = bits(insn,16,20);
1592     int rd = bits(insn,11,15);     int rd = bits(insn,11,15);
1593    
1594     cp0_exec_mtc0(cpu,rt,rd);     mips64_cp0_exec_mtc0(cpu,rt,rd);
1595     return(0);     return(0);
1596  }  }
1597    
# Line 2030  static fastcall int mips64_exec_TEQI(cpu Line 2029  static fastcall int mips64_exec_TEQI(cpu
2029  /* TLBP */  /* TLBP */
2030  static fastcall int mips64_exec_TLBP(cpu_mips_t *cpu,mips_insn_t insn)  static fastcall int mips64_exec_TLBP(cpu_mips_t *cpu,mips_insn_t insn)
2031  {  {
2032     cp0_exec_tlbp(cpu);     mips64_cp0_exec_tlbp(cpu);
2033     return(0);     return(0);
2034  }  }
2035    
2036  /* TLBR */  /* TLBR */
2037  static fastcall int mips64_exec_TLBR(cpu_mips_t *cpu,mips_insn_t insn)  static fastcall int mips64_exec_TLBR(cpu_mips_t *cpu,mips_insn_t insn)
2038  {  {
2039     cp0_exec_tlbr(cpu);     mips64_cp0_exec_tlbr(cpu);
2040     return(0);     return(0);
2041  }  }
2042    
2043  /* TLBWI */  /* TLBWI */
2044  static fastcall int mips64_exec_TLBWI(cpu_mips_t *cpu,mips_insn_t insn)  static fastcall int mips64_exec_TLBWI(cpu_mips_t *cpu,mips_insn_t insn)
2045  {  {
2046     cp0_exec_tlbwi(cpu);     mips64_cp0_exec_tlbwi(cpu);
2047     return(0);     return(0);
2048  }  }
2049    
2050  /* TLBWR */  /* TLBWR */
2051  static fastcall int mips64_exec_TLBWR(cpu_mips_t *cpu,mips_insn_t insn)  static fastcall int mips64_exec_TLBWR(cpu_mips_t *cpu,mips_insn_t insn)
2052  {  {
2053     cp0_exec_tlbwr(cpu);     mips64_cp0_exec_tlbwr(cpu);
2054     return(0);     return(0);
2055  }  }
2056    
# Line 2078  static fastcall int mips64_exec_XORI(cpu Line 2077  static fastcall int mips64_exec_XORI(cpu
2077  }  }
2078    
2079  /* MIPS instruction array */  /* MIPS instruction array */
2080  static struct insn_exec_tag mips64_exec_tags[] = {  static struct mips64_insn_exec_tag mips64_exec_tags[] = {
2081     { "li"     , mips64_exec_LI      , 0xffe00000 , 0x24000000, 1, 16 },     { "li"     , mips64_exec_LI      , 0xffe00000 , 0x24000000, 1, 16 },
2082     { "move"   , mips64_exec_MOVE    , 0xfc1f07ff , 0x00000021, 1, 15 },     { "move"   , mips64_exec_MOVE    , 0xfc1f07ff , 0x00000021, 1, 15 },
2083     { "b"      , mips64_exec_B       , 0xffff0000 , 0x10000000, 0, 10 },     { "b"      , mips64_exec_B       , 0xffff0000 , 0x10000000, 0, 10 },
# Line 2198  static struct insn_exec_tag mips64_exec_ Line 2197  static struct insn_exec_tag mips64_exec_
2197     { "tlbwr"  , mips64_exec_TLBWR   , 0xffffffff , 0x42000006, 1, 1 },     { "tlbwr"  , mips64_exec_TLBWR   , 0xffffffff , 0x42000006, 1, 1 },
2198     { "xor"    , mips64_exec_XOR     , 0xfc0007ff , 0x00000026, 1, 3 },     { "xor"    , mips64_exec_XOR     , 0xfc0007ff , 0x00000026, 1, 3 },
2199     { "xori"   , mips64_exec_XORI    , 0xfc000000 , 0x38000000, 1, 5 },     { "xori"   , mips64_exec_XORI    , 0xfc000000 , 0x38000000, 1, 5 },
2200       { "unknown", mips64_exec_unknown , 0x00000000 , 0x00000000, 1, 0 },
2201     { NULL     , NULL                , 0x00000000 , 0x00000000, 1, 0 },     { NULL     , NULL                , 0x00000000 , 0x00000000, 1, 0 },
2202  };  };
2203    

Legend:
Removed from v.5  
changed lines
  Added in v.9

  ViewVC Help
Powered by ViewVC 1.1.26