Esempio n. 1
0
void free_registers_move_start(usf_state_t * state)
{
  /* flush all dirty registers and clear needed_registers table */
  free_all_registers(state);

  /* now move the start of the new instruction down past the flushing instructions */
  simplify_access(state);
}
Esempio n. 2
0
void gensyscall(usf_state_t * state)
{
#ifdef INTERPRET_SYSCALL
   gencallinterp(state, (unsigned int)state->current_instruction_table.SYSCALL, 0);
#else
   free_all_registers(state);
   simplify_access(state);
   mov_m32_imm32(state, &state->g_cp0_regs[CP0_CAUSE_REG], 8 << 2);
   gencallinterp(state, (unsigned int)exception_general, 0);
#endif
}
Esempio n. 3
0
void gensyscall()
{
#ifdef INTERPRET_SYSCALL
   gencallinterp((unsigned long)SYSCALL, 0);
#else
   free_all_registers();
   simplify_access();
   mov_m32_imm32(&Cause, 8 << 2);
   gencallinterp((unsigned long)exception_general, 0);
#endif
}
Esempio n. 4
0
void gensyscall(void)
{
#ifdef INTERPRET_SYSCALL
    gencallinterp((unsigned int)cached_interpreter_table.SYSCALL, 0);
#else
    free_all_registers();
    simplify_access();
    mov_m32_imm32(&g_cp0_regs[CP0_CAUSE_REG], 8 << 2);
    gencallinterp((unsigned int)exception_general, 0);
#endif
}
Esempio n. 5
0
void genbltzl(void)
{
#ifdef INTERPRET_BLTZL
   gencallinterp((unsigned int)BLTZL, 1);
#else
   if (((dst->addr & 0xFFF) == 0xFFC && 
       (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
     {
    gencallinterp((unsigned int)BLTZL, 1);
    return;
     }
   
   genbltz_test();
   free_all_registers();
   gentestl();
#endif
}
Esempio n. 6
0
void genbgezl(void)
{
#ifdef INTERPRET_BGEZL
   gencallinterp((native_type)cached_interpreter_table.BGEZL, 1);
#else
   if (((dst->addr & 0xFFF) == 0xFFC && 
            (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
   {
      gencallinterp((native_type)cached_interpreter_table.BGEZL, 1);
      return;
   }

   genbgez_test();
   free_all_registers();
   gentestl();
#endif
}
Esempio n. 7
0
void genbgezl_out(void)
{
#ifdef INTERPRET_BGEZL_OUT
   gencallinterp((unsigned int)cached_interpreter_table.BGEZL_OUT, 1);
#else
   if (((dst->addr & 0xFFF) == 0xFFC && 
       (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
     {
    gencallinterp((unsigned int)cached_interpreter_table.BGEZL_OUT, 1);
    return;
     }
   
   genbgez_test();
   free_all_registers();
   gentestl_out();
#endif
}
Esempio n. 8
0
void genbc1tl_out(void)
{
#ifdef INTERPRET_BC1TL_OUT
   gencallinterp((unsigned int)BC1TL_OUT, 1);
#else
   if (((dst->addr & 0xFFF) == 0xFFC &&
       (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
     {
    gencallinterp((unsigned int)BC1TL_OUT, 1);
    return;
     }
   
   gencheck_cop1_unusable();
   genbc1t_test();
   free_all_registers();
   gentestl_out();
#endif
}
Esempio n. 9
0
File: gbc.c Progetto: cxd4/mupen86
void genbc1fl()
{
#ifdef INTERPRET_BC1FL
   gencallinterp((u32)BC1FL, 1);
#else
   if (((dst->addr & 0xFFF) == 0xFFC &&
       (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
     {
	gencallinterp((u32)BC1FL, 1);
	return;
     }
   
   gencheck_cop1_unusable();
   genbc1f_test();
   free_all_registers();
   gentestl();
#endif
}
Esempio n. 10
0
void genbc1fl_out(void)
{
#ifdef INTERPRET_BC1FL_OUT
   gencallinterp((native_type)cached_interpreter_table.BC1FL_OUT, 1);
#else
   if (((dst->addr & 0xFFF) == 0xFFC &&
            (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
   {
      gencallinterp((native_type)cached_interpreter_table.BC1FL_OUT, 1);
      return;
   }

   gencheck_cop1_unusable();
   genbc1f_test();
   free_all_registers();
   gentestl_out();
#endif
}
Esempio n. 11
0
void genbc1tl(void)
{
#ifdef INTERPRET_BC1TL
   gencallinterp((unsigned int)cached_interpreter_table.BC1TL, 1);
#else
   if (((g_dev.r4300.recomp.dst->addr & 0xFFF) == 0xFFC &&
       (g_dev.r4300.recomp.dst->addr < 0x80000000 || g_dev.r4300.recomp.dst->addr >= 0xC0000000))||g_dev.r4300.recomp.no_compiled_jump)
     {
    gencallinterp((unsigned int)cached_interpreter_table.BC1TL, 1);
    return;
     }
   
   gencheck_cop1_unusable();
   genbc1t_test();
   free_all_registers();
   gentestl();
#endif
}
Esempio n. 12
0
void genbltzall_out(void)
{
#ifdef INTERPRET_BLTZALL_OUT
   gencallinterp((native_type)cached_interpreter_table.BLTZALL_OUT, 1);
#else
   if (((dst->addr & 0xFFF) == 0xFFC && 
            (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
   {
      gencallinterp((native_type)cached_interpreter_table.BLTZALL_OUT, 1);
      return;
   }

   genbltz_test();
   genbranchlink();
   free_all_registers();
   gentestl_out();
#endif
}
Esempio n. 13
0
void genbgezl_out(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[50]);
#endif
#ifdef INTERPRET_BGEZL_OUT
   gencallinterp((unsigned long long)BGEZL_OUT, 1);
#else
   if (((dst->addr & 0xFFF) == 0xFFC && 
       (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
     {
    gencallinterp((unsigned long long)BGEZL_OUT, 1);
    return;
     }
   
   genbgez_test();
   free_all_registers();
   gentestl_out();
#endif
}
Esempio n. 14
0
void genbltzall(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[53]);
#endif
#ifdef INTERPRET_BLTZALL
   gencallinterp((unsigned long long)BLTZALL, 1);
#else
   if (((dst->addr & 0xFFF) == 0xFFC && 
       (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
     {
    gencallinterp((unsigned long long)BLTZALL, 1);
    return;
     }
   
   genbltz_test();
   genbranchlink();
   free_all_registers();
   gentestl();
#endif
}
Esempio n. 15
0
void genbc1tl_out(usf_state_t * state)
{
#if defined(COUNT_INSTR)
   inc_m32rel(state, &state->instr_count[103]);
#endif
#ifdef INTERPRET_BC1TL_OUT
   gencallinterp(state, (unsigned long long)state->current_instruction_table.BC1TL_OUT, 1);
#else
   if (((state->dst->addr & 0xFFF) == 0xFFC &&
       (state->dst->addr < 0x80000000 || state->dst->addr >= 0xC0000000))||state->no_compiled_jump)
     {
    gencallinterp(state, (unsigned long long)state->current_instruction_table.BC1TL_OUT, 1);
    return;
     }
   
   gencheck_cop1_unusable(state);
   genbc1t_test(state);
   free_all_registers(state);
   gentestl_out(state);
#endif
}
Esempio n. 16
0
void gendmultu(void)
{
#ifdef INTERPRET_DMULTU
   gencallinterp((unsigned int)cached_interpreter_table.DMULTU, 0);
#else
   free_all_registers();
   simplify_access();
   
   mov_eax_memoffs32((unsigned int *)g_dev.r4300.recomp.dst->f.r.rs);
   mul_m32((unsigned int *)g_dev.r4300.recomp.dst->f.r.rt); // EDX:EAX = temp1
   mov_memoffs32_eax((unsigned int *)(r4300_mult_lo()));
   
   mov_reg32_reg32(EBX, EDX); // EBX = temp1>>32
   mov_eax_memoffs32((unsigned int *)g_dev.r4300.recomp.dst->f.r.rs);
   mul_m32((unsigned int *)(g_dev.r4300.recomp.dst->f.r.rt)+1);
   add_reg32_reg32(EBX, EAX);
   adc_reg32_imm32(EDX, 0);
   mov_reg32_reg32(ECX, EDX); // ECX:EBX = temp2
   
   mov_eax_memoffs32((unsigned int *)(g_dev.r4300.recomp.dst->f.r.rs)+1);
   mul_m32((unsigned int *)g_dev.r4300.recomp.dst->f.r.rt); // EDX:EAX = temp3
   
   add_reg32_reg32(EBX, EAX);
   adc_reg32_imm32(ECX, 0); // ECX:EBX = result2
   mov_m32_reg32((unsigned int*)(r4300_mult_lo())+1, EBX);
   
   mov_reg32_reg32(ESI, EDX); // ESI = temp3>>32
   mov_eax_memoffs32((unsigned int *)(g_dev.r4300.recomp.dst->f.r.rs)+1);
   mul_m32((unsigned int *)(g_dev.r4300.recomp.dst->f.r.rt)+1);
   add_reg32_reg32(EAX, ESI);
   adc_reg32_imm32(EDX, 0); // EDX:EAX = temp4
   
   add_reg32_reg32(EAX, ECX);
   adc_reg32_imm32(EDX, 0); // EDX:EAX = result3
   mov_memoffs32_eax((unsigned int *)(r4300_mult_hi()));
   mov_m32_reg32((unsigned int *)(r4300_mult_hi())+1, EDX);
#endif
}
Esempio n. 17
0
void gendmultu(usf_state_t * state)
{
#ifdef INTERPRET_DMULTU
   gencallinterp(state, (unsigned int)state->current_instruction_table.DMULTU, 0);
#else
   free_all_registers(state);
   simplify_access(state);
   
   mov_eax_memoffs32(state, (unsigned int *)state->dst->f.r.rs);
   mul_m32(state, (unsigned int *)state->dst->f.r.rt); // EDX:EAX = temp1
   mov_memoffs32_eax(state, (unsigned int *)(&state->lo));
   
   mov_reg32_reg32(state, EBX, EDX); // EBX = temp1>>32
   mov_eax_memoffs32(state, (unsigned int *)state->dst->f.r.rs);
   mul_m32(state, (unsigned int *)(state->dst->f.r.rt)+1);
   add_reg32_reg32(state, EBX, EAX);
   adc_reg32_imm32(state, EDX, 0);
   mov_reg32_reg32(state, ECX, EDX); // ECX:EBX = temp2
   
   mov_eax_memoffs32(state, (unsigned int *)(state->dst->f.r.rs)+1);
   mul_m32(state, (unsigned int *)state->dst->f.r.rt); // EDX:EAX = temp3
   
   add_reg32_reg32(state, EBX, EAX);
   adc_reg32_imm32(state, ECX, 0); // ECX:EBX = result2
   mov_m32_reg32(state, (unsigned int*)(&state->lo)+1, EBX);
   
   mov_reg32_reg32(state, EDI, EDX); // EDI = temp3>>32
   mov_eax_memoffs32(state, (unsigned int *)(state->dst->f.r.rs)+1);
   mul_m32(state, (unsigned int *)(state->dst->f.r.rt)+1);
   add_reg32_reg32(state, EAX, EDI);
   adc_reg32_imm32(state, EDX, 0); // EDX:EAX = temp4
   
   add_reg32_reg32(state, EAX, ECX);
   adc_reg32_imm32(state, EDX, 0); // EDX:EAX = result3
   mov_memoffs32_eax(state,(unsigned int *)(&state->hi));
   mov_m32_reg32(state, (unsigned int *)(&state->hi)+1, EDX);
#endif
}
Esempio n. 18
0
void gendmultu()
{
#ifdef INTERPRET_DMULTU
   gencallinterp((unsigned long)DMULTU, 0);
#else
   free_all_registers();
   simplify_access();
   
   mov_eax_memoffs32((unsigned long *)dst->f.r.rs);
   mul_m32((unsigned long *)dst->f.r.rt); // EDX:EAX = temp1
   mov_memoffs32_eax((unsigned long *)(&lo));
   
   mov_reg32_reg32(EBX, EDX); // EBX = temp1>>32
   mov_eax_memoffs32((unsigned long *)dst->f.r.rs);
   mul_m32((unsigned long *)(dst->f.r.rt)+1);
   add_reg32_reg32(EBX, EAX);
   adc_reg32_imm32(EDX, 0);
   mov_reg32_reg32(ECX, EDX); // ECX:EBX = temp2
   
   mov_eax_memoffs32((unsigned long *)(dst->f.r.rs)+1);
   mul_m32((unsigned long *)dst->f.r.rt); // EDX:EAX = temp3
   
   add_reg32_reg32(EBX, EAX);
   adc_reg32_imm32(ECX, 0); // ECX:EBX = result2
   mov_m32_reg32((unsigned long*)(&lo)+1, EBX);
   
   mov_reg32_reg32(ESI, EDX); // ESI = temp3>>32
   mov_eax_memoffs32((unsigned long *)(dst->f.r.rs)+1);
   mul_m32((unsigned long *)(dst->f.r.rt)+1);
   add_reg32_reg32(EAX, ESI);
   adc_reg32_imm32(EDX, 0); // EDX:EAX = temp4
   
   add_reg32_reg32(EAX, ECX);
   adc_reg32_imm32(EDX, 0); // EDX:EAX = result3
   mov_memoffs32_eax((unsigned long *)(&hi));
   mov_m32_reg32((unsigned long *)(&hi)+1, EDX);
#endif
}
Esempio n. 19
0
void print_text_segment() {
    int i;
    instr_t *instr;

    printf("\n");
    printf(".text\n");
    printf(".global main\n");

    for(i=0;i<MAX_NUM_OF_MODULES;i++) {
        instr = final_tree[i];
        if (!instr) {
            return;
        }

        free_all_registers();
        while (instr) {
            register_allocate(instr);
            print_instr(instr);
            register_free(instr);
            instr = instr->next;
        }
        printf("\n");
    }
}
Esempio n. 20
0
void genjalr(void)
{
#ifdef INTERPRET_JALR
   gencallinterp((unsigned int)cached_interpreter_table.JALR, 0);
#else
   unsigned int diff =
     (unsigned int)(&g_dev.r4300.recomp.dst->local_addr) - (unsigned int)(g_dev.r4300.recomp.dst);
   unsigned int diff_need =
     (unsigned int)(&g_dev.r4300.recomp.dst->reg_cache_infos.need_map) - (unsigned int)(g_dev.r4300.recomp.dst);
   unsigned int diff_wrap =
     (unsigned int)(&g_dev.r4300.recomp.dst->reg_cache_infos.jump_wrapper) - (unsigned int)(g_dev.r4300.recomp.dst);
   
   if (((g_dev.r4300.recomp.dst->addr & 0xFFF) == 0xFFC && 
       (g_dev.r4300.recomp.dst->addr < 0x80000000 || g_dev.r4300.recomp.dst->addr >= 0xC0000000))||g_dev.r4300.recomp.no_compiled_jump)
     {
    gencallinterp((unsigned int)cached_interpreter_table.JALR, 1);
    return;
     }
   
   free_all_registers();
   simplify_access();
   mov_eax_memoffs32((unsigned int *)g_dev.r4300.recomp.dst->f.r.rs);
   mov_memoffs32_eax((unsigned int *)&g_dev.r4300.local_rs);
   
   gendelayslot();
   
   mov_m32_imm32((unsigned int *)(g_dev.r4300.recomp.dst-1)->f.r.rd, g_dev.r4300.recomp.dst->addr+4);
   if ((g_dev.r4300.recomp.dst->addr+4) & 0x80000000)
     mov_m32_imm32(((unsigned int *)(g_dev.r4300.recomp.dst-1)->f.r.rd)+1, 0xFFFFFFFF);
   else
     mov_m32_imm32(((unsigned int *)(g_dev.r4300.recomp.dst-1)->f.r.rd)+1, 0);
   
   mov_eax_memoffs32((unsigned int *)&g_dev.r4300.local_rs);
   mov_memoffs32_eax((unsigned int *)&g_dev.r4300.cp0.last_addr);
   
   gencheck_interupt_reg();
   
   mov_eax_memoffs32((unsigned int *)&g_dev.r4300.local_rs);
   mov_reg32_reg32(EBX, EAX);
   and_eax_imm32(0xFFFFF000);
   cmp_eax_imm32(g_dev.r4300.recomp.dst_block->start & 0xFFFFF000);
   je_near_rj(0);

   jump_start_rel32();
   
   mov_m32_reg32(&g_dev.r4300.cached_interp.jump_to_address, EBX);
   mov_m32_imm32((unsigned int*)(&(*r4300_pc_struct())), (unsigned int)(g_dev.r4300.recomp.dst+1));
   mov_reg32_imm32(EAX, (unsigned int)jump_to_func);
   call_reg32(EAX);
   
   jump_end_rel32();
   
   mov_reg32_reg32(EAX, EBX);
   sub_eax_imm32(g_dev.r4300.recomp.dst_block->start);
   shr_reg32_imm8(EAX, 2);
   mul_m32((unsigned int *)(&precomp_instr_size));
   
   mov_reg32_preg32pimm32(EBX, EAX, (unsigned int)(g_dev.r4300.recomp.dst_block->block)+diff_need);
   cmp_reg32_imm32(EBX, 1);
   jne_rj(7);
   
   add_eax_imm32((unsigned int)(g_dev.r4300.recomp.dst_block->block)+diff_wrap); // 5
   jmp_reg32(EAX); // 2
   
   mov_reg32_preg32pimm32(EAX, EAX, (unsigned int)(g_dev.r4300.recomp.dst_block->block)+diff);
   add_reg32_m32(EAX, (unsigned int *)(&g_dev.r4300.recomp.dst_block->code));
   
   jmp_reg32(EAX);
#endif
}
Esempio n. 21
0
void init_reg() {
    arch[0]  = &R_zero;
    arch[1]  = &R_at;
    arch[2]  = &R_v0;
    arch[3]  = &R_v1;
    arch[4]  = &R_a0;
    arch[5]  = &R_a1;
    arch[6]  = &R_a2;
    arch[7]  = &R_a3;
    arch[8]  = &R_t0;
    arch[9]  = &R_t1;
    arch[10] = &R_t2;
    arch[11] = &R_t3;
    arch[12] = &R_t4;
    arch[13] = &R_t5;
    arch[14] = &R_t6;
    arch[15] = &R_t7;
    arch[16] = &R_s0;
    arch[17] = &R_s1;
    arch[18] = &R_s2;
    arch[19] = &R_s3;
    arch[20] = &R_s4;
    arch[21] = &R_s5;
    arch[22] = &R_s6;
    arch[23] = &R_s7;
    arch[24] = &R_t8;
    arch[25] = &R_t9;
    arch[26] = &R_k0;
    arch[27] = &R_k1;
    arch[28] = &R_gp;
    arch[29] = &R_sp;
    arch[30] = &R_fp;
    arch[31] = &R_ra;

    arch_fp[0] = &FP_0;
    arch_fp[1] = &FP_1;
    arch_fp[2] = &FP_2;
    arch_fp[3] = &FP_3;
    arch_fp[4] = &FP_4;
    arch_fp[5] = &FP_5;
    arch_fp[6] = &FP_6;
    arch_fp[7] = &FP_7;
    arch_fp[8] = &FP_8;
    arch_fp[9] = &FP_9;
    arch_fp[10] = &FP_10;
    arch_fp[11] = &FP_11;
    arch_fp[12] = &FP_12;
    arch_fp[13] = &FP_13;
    arch_fp[14] = &FP_14;
    arch_fp[15] = &FP_15;
    arch_fp[16] = &FP_16;
    arch_fp[17] = &FP_17;
    arch_fp[18] = &FP_18;
    arch_fp[19] = &FP_19;
    arch_fp[20] = &FP_20;
    arch_fp[21] = &FP_21;
    arch_fp[22] = &FP_22;
    arch_fp[23] = &FP_23;
    arch_fp[24] = &FP_24;
    arch_fp[25] = &FP_25;
    arch_fp[26] = &FP_26;
    arch_fp[27] = &FP_27;
    arch_fp[28] = &FP_28;
    arch_fp[29] = &FP_29;
    arch_fp[30] = &FP_30;
    arch_fp[31] = &FP_31;

    free_all_registers();
}
Esempio n. 22
0
void genjalr()
{
#ifdef INTERPRET_JALR
   gencallinterp((unsigned long)JALR, 0);
#else
   static unsigned long precomp_instr_size = sizeof(precomp_instr);
   unsigned long diff = 
     (unsigned long)(&dst->local_addr) - (unsigned long)(dst);
   unsigned long diff_need = 
     (unsigned long)(&dst->reg_cache_infos.need_map) - (unsigned long)(dst);
   unsigned long diff_wrap = 
     (unsigned long)(&dst->reg_cache_infos.jump_wrapper) - (unsigned long)(dst);
   unsigned long temp, temp2;
   
   if (((dst->addr & 0xFFF) == 0xFFC && 
       (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
     {
	gencallinterp((unsigned long)JALR, 1);
	return;
     }
   
   free_all_registers();
   simplify_access();
   mov_eax_memoffs32((unsigned long *)dst->f.r.rs);
   mov_memoffs32_eax((unsigned long *)&local_rs);
   
   gendelayslot();
   
   mov_m32_imm32((unsigned long *)(dst-1)->f.r.rd, dst->addr+4);
   if ((dst->addr+4) & 0x80000000)
     mov_m32_imm32(((unsigned long *)(dst-1)->f.r.rd)+1, 0xFFFFFFFF);
   else
     mov_m32_imm32(((unsigned long *)(dst-1)->f.r.rd)+1, 0);
   
   mov_eax_memoffs32((unsigned long *)&local_rs);
   mov_memoffs32_eax((unsigned long *)&last_addr);
   
   gencheck_interupt_reg();
   
   mov_eax_memoffs32((unsigned long *)&local_rs);
   mov_reg32_reg32(EBX, EAX);
   and_eax_imm32(0xFFFFF000);
   cmp_eax_imm32(dst_block->start & 0xFFFFF000);
   je_near_rj(0);
   temp = code_length;
   
   mov_m32_reg32(&jump_to_address, EBX);
   mov_m32_imm32((unsigned long*)(&PC), (unsigned long)(dst+1));
   mov_reg32_imm32(EAX, (unsigned long)jump_to_func);
   call_reg32(EAX);
   
   temp2 = code_length;
   code_length = temp-4;
   put32(temp2 - temp);
   code_length = temp2;
   
   mov_reg32_reg32(EAX, EBX);
   sub_eax_imm32(dst_block->start);
   shr_reg32_imm8(EAX, 2);
   mul_m32((unsigned long *)(&precomp_instr_size));
   
   mov_reg32_preg32pimm32(EBX, EAX, (unsigned long)(dst_block->block)+diff_need);
   cmp_reg32_imm32(EBX, 1);
   jne_rj(7);
   
   add_eax_imm32((unsigned long)(dst_block->block)+diff_wrap); // 5
   jmp_reg32(EAX); // 2
   
   mov_reg32_preg32pimm32(EAX, EAX, (unsigned long)(dst_block->block)+diff);
   add_reg32_m32(EAX, (unsigned long *)(&dst_block->code));
   
   jmp_reg32(EAX);
#endif
}
Esempio n. 23
0
void genjalr(usf_state_t * state)
{
#ifdef INTERPRET_JALR
   gencallinterp(state, (unsigned int)state->current_instruction_table.JALR, 0);
#else
   unsigned int diff =
     (unsigned int)(&state->dst->local_addr) - (unsigned int)(state->dst);
   unsigned int diff_need =
     (unsigned int)(&state->dst->reg_cache_infos.need_map) - (unsigned int)(state->dst);
   unsigned int diff_wrap =
     (unsigned int)(&state->dst->reg_cache_infos.jump_wrapper) - (unsigned int)(state->dst);
   
   if (((state->dst->addr & 0xFFF) == 0xFFC &&
       (state->dst->addr < 0x80000000 || state->dst->addr >= 0xC0000000))||state->no_compiled_jump)
     {
    gencallinterp(state, (unsigned int)state->current_instruction_table.JALR, 1);
    return;
     }
   
   free_all_registers(state);
   simplify_access(state);
   mov_eax_memoffs32(state, (unsigned int *)state->dst->f.r.rs);
   mov_memoffs32_eax(state, (unsigned int *)&state->local_rs);
   
   gendelayslot(state);
   
   mov_m32_imm32(state, (unsigned int *)(state->dst-1)->f.r.rd, state->dst->addr+4);
   if ((state->dst->addr+4) & 0x80000000)
     mov_m32_imm32(state, ((unsigned int *)(state->dst-1)->f.r.rd)+1, 0xFFFFFFFF);
   else
     mov_m32_imm32(state, ((unsigned int *)(state->dst-1)->f.r.rd)+1, 0);
   
   mov_eax_memoffs32(state, (unsigned int *)&state->local_rs);
   mov_memoffs32_eax(state, (unsigned int *)&state->last_addr);
   
   gencheck_interupt_reg(state);
   
   mov_eax_memoffs32(state, (unsigned int *)&state->local_rs);
   mov_reg32_reg32(state, EBX, EAX);
   and_eax_imm32(state, 0xFFFFF000);
   cmp_eax_imm32(state, state->dst_block->start & 0xFFFFF000);
   je_near_rj(state, 0);

   jump_start_rel32(state);
   
   mov_m32_reg32(state, &state->jump_to_address, EBX);
   mov_m32_imm32(state, (unsigned int*)(&state->PC), (unsigned int)(state->dst+1));
   mov_reg32_imm32(state, EBX, (unsigned int)jump_to_func);
   mov_reg32_reg32(state, RP0, ESI);
   call_reg32(state, EBX);

   jump_end_rel32(state);
   
   mov_reg32_reg32(state, EAX, EBX);
   sub_eax_imm32(state, state->dst_block->start);
   shr_reg32_imm8(state, EAX, 2);
   mul_m32(state, (unsigned int *)(&state->precomp_instr_size));
   
   mov_reg32_preg32pimm32(state, EBX, EAX, (unsigned int)(state->dst_block->block)+diff_need);
   cmp_reg32_imm32(state, EBX, 1);
   jne_rj(state, 7);
   
   add_eax_imm32(state, (unsigned int)(state->dst_block->block)+diff_wrap); // 5
   jmp_reg32(state, EAX); // 2
   
   mov_reg32_preg32pimm32(state, EAX, EAX, (unsigned int)(state->dst_block->block)+diff);
   add_reg32_m32(state, EAX, (unsigned int *)(&state->dst_block->code));
   
   jmp_reg32(state, EAX);
#endif
}
Esempio n. 24
0
void genjr(void)
{
#ifdef INTERPRET_JR
    gencallinterp((unsigned int)cached_interpreter_table.JR, 1);
#else
    static unsigned int precomp_instr_size = sizeof(precomp_instr);
    unsigned int diff =
        (unsigned int)(&dst->local_addr) - (unsigned int)(dst);
    unsigned int diff_need =
        (unsigned int)(&dst->reg_cache_infos.need_map) - (unsigned int)(dst);
    unsigned int diff_wrap =
        (unsigned int)(&dst->reg_cache_infos.jump_wrapper) - (unsigned int)(dst);

    if (((dst->addr & 0xFFF) == 0xFFC &&
            (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
    {
        gencallinterp((unsigned int)cached_interpreter_table.JR, 1);
        return;
    }

    free_all_registers();
    simplify_access();
    mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
    mov_memoffs32_eax((unsigned int *)&local_rs);

    gendelayslot();

    mov_eax_memoffs32((unsigned int *)&local_rs);
    mov_memoffs32_eax((unsigned int *)&last_addr);

    gencheck_interupt_reg();

    mov_eax_memoffs32((unsigned int *)&local_rs);
    mov_reg32_reg32(EBX, EAX);
    and_eax_imm32(0xFFFFF000);
    cmp_eax_imm32(dst_block->start & 0xFFFFF000);
    je_near_rj(0);

    jump_start_rel32();

    mov_m32_reg32(&jump_to_address, EBX);
    mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
    mov_reg32_imm32(EAX, (unsigned int)jump_to_func);
    call_reg32(EAX);

    jump_end_rel32();

    mov_reg32_reg32(EAX, EBX);
    sub_eax_imm32(dst_block->start);
    shr_reg32_imm8(EAX, 2);
    mul_m32((unsigned int *)(&precomp_instr_size));

    mov_reg32_preg32pimm32(EBX, EAX, (unsigned int)(dst_block->block)+diff_need);
    cmp_reg32_imm32(EBX, 1);
    jne_rj(7);

    add_eax_imm32((unsigned int)(dst_block->block)+diff_wrap); // 5
    jmp_reg32(EAX); // 2

    mov_reg32_preg32pimm32(EAX, EAX, (unsigned int)(dst_block->block)+diff);
    add_reg32_m32(EAX, (unsigned int *)(&dst_block->code));

    jmp_reg32(EAX);
#endif
}