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

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

upstream/dynamips-0.2.7-RC1/mips64_x86_trans.c revision 7 by dpavlin, Sat Oct 6 16:23:47 2007 UTC trunk/mips64_x86_trans.c revision 12 by dpavlin, Sat Oct 6 16:45:40 2007 UTC
# Line 82  void mips64_set_ra(mips64_jit_tcb_t *b,m Line 82  void mips64_set_ra(mips64_jit_tcb_t *b,m
82     x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(MIPS_GPR_RA)+4,X86_EDX,4);     x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(MIPS_GPR_RA)+4,X86_EDX,4);
83  }  }
84    
85    /*
86     * Try to branch directly to the specified JIT block without returning to
87     * main loop.
88     */
89    static void mips64_try_direct_far_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b,
90                                           m_uint64_t new_pc)
91    {
92       m_uint64_t new_page;
93       m_uint32_t pc_hash,pc_offset;
94       u_char *test1,*test2,*test3,*test4;
95    
96       new_page = new_pc & MIPS_MIN_PAGE_MASK;
97       pc_offset = (new_pc & MIPS_MIN_PAGE_IMASK) >> 2;
98       pc_hash = mips64_jit_get_pc_hash(new_pc);
99    
100       /* Get JIT block info in %edx */
101       x86_mov_reg_membase(b->jit_ptr,X86_EBX,
102                           X86_EDI,OFFSET(cpu_mips_t,exec_blk_map),4);
103       x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EBX,pc_hash*sizeof(void *),4);
104    
105       /* no JIT block found ? */
106       x86_test_reg_reg(b->jit_ptr,X86_EDX,X86_EDX);
107       test1 = b->jit_ptr;
108       x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
109    
110       /* Check block PC (lower 32-bits first) */
111       x86_mov_reg_imm(b->jit_ptr,X86_EAX,(m_uint32_t)new_page);
112       x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EAX,X86_EDX,
113                           OFFSET(mips64_jit_tcb_t,start_pc));
114       test2 = b->jit_ptr;
115       x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
116    
117       /* Check higher bits... */
118       x86_mov_reg_imm(b->jit_ptr,X86_ECX,new_page >> 32);
119       x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_ECX,X86_EDX,
120                           OFFSET(mips64_jit_tcb_t,start_pc)+4);
121       test3 = b->jit_ptr;
122       x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
123    
124       /* Jump to the code */
125       x86_mov_reg_membase(b->jit_ptr,X86_ESI,
126                           X86_EDX,OFFSET(mips64_jit_tcb_t,jit_insn_ptr),4);
127       x86_mov_reg_membase(b->jit_ptr,X86_EBX,
128                           X86_ESI,pc_offset * sizeof(void *),4);
129      
130       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
131       test4 = b->jit_ptr;
132       x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
133       x86_jump_reg(b->jit_ptr,X86_EBX);
134    
135       /* Returns to caller... */
136       x86_patch(test1,b->jit_ptr);
137       x86_patch(test2,b->jit_ptr);
138       x86_patch(test3,b->jit_ptr);
139       x86_patch(test4,b->jit_ptr);
140    
141       mips64_set_pc(b,new_pc);
142       mips64_jit_tcb_push_epilog(b);
143    }
144    
145  /* Set Jump */  /* Set Jump */
146  static void mips64_set_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b,  static void mips64_set_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b,
147                              m_uint64_t new_pc,int local_jump)                              m_uint64_t new_pc,int local_jump)
# Line 96  static void mips64_set_jump(cpu_mips_t * Line 156  static void mips64_set_jump(cpu_mips_t *
156        if (jump_ptr) {        if (jump_ptr) {
157           x86_jump_code(b->jit_ptr,jump_ptr);           x86_jump_code(b->jit_ptr,jump_ptr);
158        } else {        } else {
159             /* Never jump directly to code in a delay slot */
160             if (mips64_jit_is_delay_slot(b,new_pc)) {
161                mips64_set_pc(b,new_pc);
162                mips64_jit_tcb_push_epilog(b);
163                return;
164             }
165    
166           mips64_jit_tcb_record_patch(b,b->jit_ptr,new_pc);           mips64_jit_tcb_record_patch(b,b->jit_ptr,new_pc);
167           x86_jump32(b->jit_ptr,0);           x86_jump32(b->jit_ptr,0);
168        }        }
169     } else {     } else {
170        /* save PC */        if (cpu->exec_blk_direct_jump) {
171        mips64_set_pc(b,new_pc);           /* Block lookup optimization */
172             mips64_try_direct_far_jump(cpu,b,new_pc);
173        /* address is in another block, for now, returns to caller */        } else {
174        mips64_jit_tcb_push_epilog(b);           mips64_set_pc(b,new_pc);
175             mips64_jit_tcb_push_epilog(b);
176          }
177     }     }
178  }  }
179    
# Line 158  static void mips64_emit_memop_fast64(mip Line 227  static void mips64_emit_memop_fast64(mip
227                                       memop_fast_access op_handler)                                       memop_fast_access op_handler)
228  {  {
229     m_uint64_t val = sign_extend(offset,16);     m_uint64_t val = sign_extend(offset,16);
230     u_char *test1,*test2,*test3,*p_exception,*p_exit;     u_char *test1,*test2,*test3,*p_exit;
231    
232     test3 = NULL;     test3 = NULL;
233    
# Line 241  static void mips64_emit_memop_fast64(mip Line 310  static void mips64_emit_memop_fast64(mip
310     x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(opcode));     x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(opcode));
311     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
312    
    /* Check for exception */  
    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);  
    p_exception = b->jit_ptr;  
    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);  
    mips64_jit_tcb_push_epilog(b);  
   
313     x86_patch(p_exit,b->jit_ptr);     x86_patch(p_exit,b->jit_ptr);
    x86_patch(p_exception,b->jit_ptr);  
314  }  }
315    
316  /* Fast memory operation (32-bit) */  /* Fast memory operation (32-bit) */
# Line 258  static void mips64_emit_memop_fast32(mip Line 320  static void mips64_emit_memop_fast32(mip
320                                       memop_fast_access op_handler)                                       memop_fast_access op_handler)
321  {  {
322     m_uint32_t val = sign_extend(offset,16);     m_uint32_t val = sign_extend(offset,16);
323     u_char *test1,*test2,*p_exception,*p_exit;     u_char *test1,*test2,*p_exit;
324    
325     test2 = NULL;     test2 = NULL;
326    
# Line 336  static void mips64_emit_memop_fast32(mip Line 398  static void mips64_emit_memop_fast32(mip
398     x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(opcode));     x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(opcode));
399     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
400    
    /* Check for exception */  
    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);  
    p_exception = b->jit_ptr;  
    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);  
    mips64_jit_tcb_push_epilog(b);  
   
401     x86_patch(p_exit,b->jit_ptr);     x86_patch(p_exit,b->jit_ptr);
    x86_patch(p_exception,b->jit_ptr);  
402  }  }
403    
404  /* Fast memory operation */  /* Fast memory operation */
# Line 370  static void mips64_emit_memop(mips64_jit Line 425  static void mips64_emit_memop(mips64_jit
425                                int target,int keep_ll_bit)                                int target,int keep_ll_bit)
426  {  {
427     m_uint64_t val = sign_extend(offset,16);     m_uint64_t val = sign_extend(offset,16);
    u_char *test1;  
428    
429     /* Save PC for exception handling */     /* Save PC for exception handling */
430     mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));     mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
# Line 402  static void mips64_emit_memop(mips64_jit Line 456  static void mips64_emit_memop(mips64_jit
456     x86_push_reg(b->jit_ptr,X86_EBX);     x86_push_reg(b->jit_ptr,X86_EBX);
457     x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(op));     x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(op));
458     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
   
    /* Exception ? */  
    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);  
    test1 = b->jit_ptr;  
    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);  
    mips64_jit_tcb_push_epilog(b);  
    x86_patch(test1,b->jit_ptr);  
459  }  }
460    
461  /* Coprocessor Register transfert operation */  /* Coprocessor Register transfert operation */
# Line 432  static void mips64_emit_cp_xfr_op(mips64 Line 479  static void mips64_emit_cp_xfr_op(mips64
479  /* Virtual Breakpoint */  /* Virtual Breakpoint */
480  void mips64_emit_breakpoint(mips64_jit_tcb_t *b)  void mips64_emit_breakpoint(mips64_jit_tcb_t *b)
481  {  {
482       x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,12);
483     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
484     mips64_emit_c_call(b,mips64_run_breakpoint);     mips64_emit_c_call(b,mips64_run_breakpoint);
485       x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
486  }  }
487    
488  /* Unknown opcode handler */  /* Unknown opcode handler */
# Line 473  static fastcall void mips64_invalid_dela Line 522  static fastcall void mips64_invalid_dela
522  /* Emit unhandled instruction code */  /* Emit unhandled instruction code */
523  int mips64_emit_invalid_delay_slot(mips64_jit_tcb_t *b)  int mips64_emit_invalid_delay_slot(mips64_jit_tcb_t *b)
524  {    {  
525       x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,12);
526     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
527     mips64_emit_c_call(b,mips64_invalid_delay_slot);     mips64_emit_c_call(b,mips64_invalid_delay_slot);
528       x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
529      
530     mips64_jit_tcb_push_epilog(b);     mips64_jit_tcb_push_epilog(b);
531     return(0);     return(0);
532  }  }
533    
 /* Located in external assembly module */  
 #ifdef FAST_ASM  
 extern void mips64_inc_cp0_cnt_asm(void);  
 #endif  
   
534  /*  /*
535   * Increment count register and trigger the timer IRQ if value in compare   * Increment count register and trigger the timer IRQ if value in compare
536   * register is the same.   * register is the same.
# Line 491  extern void mips64_inc_cp0_cnt_asm(void) Line 538  extern void mips64_inc_cp0_cnt_asm(void)
538  void mips64_inc_cp0_count_reg(mips64_jit_tcb_t *b)  void mips64_inc_cp0_count_reg(mips64_jit_tcb_t *b)
539  {  {
540     x86_inc_membase(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,cp0_virt_cnt_reg));     x86_inc_membase(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,cp0_virt_cnt_reg));
   
 #if 0 /* TIMER_IRQ */  
 #ifdef FAST_ASM  
    mips64_emit_basic_c_call(b,mips64_inc_cp0_cnt_asm);  
 #else  
    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);  
    mips64_emit_basic_c_call(b,mips64_exec_inc_cp0_cnt);  
 #endif  
 #endif  
541  }  }
542    
543  /* Check if there are pending IRQ */  /* Check if there are pending IRQ */
# Line 528  void mips64_check_pending_irq(mips64_jit Line 566  void mips64_check_pending_irq(mips64_jit
566  /* Increment the number of executed instructions (performance debugging) */  /* Increment the number of executed instructions (performance debugging) */
567  void mips64_inc_perf_counter(mips64_jit_tcb_t *b)  void mips64_inc_perf_counter(mips64_jit_tcb_t *b)
568  {  {
569     x86_alu_membase_imm(b->jit_ptr,X86_ADD,     x86_inc_membase(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,perf_counter));
                        X86_EDI,OFFSET(cpu_mips_t,perf_counter),1);  
    x86_alu_membase_imm(b->jit_ptr,X86_ADC,  
                        X86_EDI,OFFSET(cpu_mips_t,perf_counter)+4,0);  
570  }  }
571    
572  /* ADD */  /* ADD */
# Line 1352  DECLARE_INSN(BREAK) Line 1387  DECLARE_INSN(BREAK)
1387  {        {      
1388     u_int code = bits(insn,6,25);     u_int code = bits(insn,6,25);
1389    
1390       x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,12);
1391     x86_mov_reg_imm(b->jit_ptr,X86_EDX,code);     x86_mov_reg_imm(b->jit_ptr,X86_EDX,code);
1392     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
1393     mips64_emit_basic_c_call(b,mips64_exec_break);     mips64_emit_basic_c_call(b,mips64_exec_break);
1394       x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
1395    
1396     mips64_jit_tcb_push_epilog(b);     mips64_jit_tcb_push_epilog(b);
1397     return(0);     return(0);
1398  }  }
# Line 2754  DECLARE_INSN(TEQ) Line 2792  DECLARE_INSN(TEQ)
2792     x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);     x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
2793    
2794     /* Generate trap exception */     /* Generate trap exception */
2795       x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,12);
2796     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
2797     mips64_emit_c_call(b,mips64_trigger_trap_exception);     mips64_emit_c_call(b,mips64_trigger_trap_exception);
2798       x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
2799      
2800     mips64_jit_tcb_push_epilog(b);     mips64_jit_tcb_push_epilog(b);
2801    
2802     /* end */     /* end */
# Line 2788  DECLARE_INSN(TEQI) Line 2829  DECLARE_INSN(TEQI)
2829     x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);     x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
2830    
2831     /* Generate trap exception */     /* Generate trap exception */
2832       x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,12);
2833     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
2834     mips64_emit_c_call(b,mips64_trigger_trap_exception);     mips64_emit_c_call(b,mips64_trigger_trap_exception);
2835       x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
2836    
2837     mips64_jit_tcb_push_epilog(b);     mips64_jit_tcb_push_epilog(b);
2838    
2839     /* end */     /* end */
# Line 2994  struct mips64_insn_tag mips64_insn_tags[ Line 3038  struct mips64_insn_tag mips64_insn_tags[
3038     { mips64_emit_XOR     , 0xfc0007ff , 0x00000026, 1 },     { mips64_emit_XOR     , 0xfc0007ff , 0x00000026, 1 },
3039     { mips64_emit_XORI    , 0xfc000000 , 0x38000000, 1 },     { mips64_emit_XORI    , 0xfc000000 , 0x38000000, 1 },
3040     { mips64_emit_unknown , 0x00000000 , 0x00000000, 1 },     { mips64_emit_unknown , 0x00000000 , 0x00000000, 1 },
3041       { NULL                , 0x00000000 , 0x00000000, 0 },
3042  };  };

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

  ViewVC Help
Powered by ViewVC 1.1.26