void gensltu(void)
{
#ifdef INTERPRET_SLTU
   gencallinterp((unsigned int)cached_interpreter_table.SLTU, 0);
#else
   int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
   int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
   int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
   int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
   int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
   
   cmp_reg32_reg32(rs2, rt2);
   jb_rj(13);
   jne_rj(4); // 2
   cmp_reg32_reg32(rs1, rt1); // 2
   jb_rj(7); // 2
   mov_reg32_imm32(rd, 0); // 5
   jmp_imm_short(5); // 2
   mov_reg32_imm32(rd, 1); // 5
#endif
}
Beispiel #2
0
void genc_un_s(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[118]);
#endif
#ifdef INTERPRET_C_UN_S
   gencallinterp((unsigned long long)cached_interpreter_table.C_UN_S, 0);
#else
   gencheck_cop1_unusable();
   mov_xreg64_m64rel(RAX, (unsigned long long *)(&reg_cop1_simple[dst->f.cf.ft]));
   fld_preg64_dword(RAX);
   mov_xreg64_m64rel(RAX, (unsigned long long *)(&reg_cop1_simple[dst->f.cf.fs]));
   fld_preg64_dword(RAX);
   fucomip_fpreg(1);
   ffree_fpreg(0);
   jp_rj(13);
   and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11
   jmp_imm_short(11); // 2
   or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11
#endif
}
void gendsra(void)
{
#ifdef INTERPRET_DSRA
   gencallinterp((unsigned int)cached_interpreter_table.DSRA, 0);
#else
   int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
   int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
   int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
   int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
   
   mov_reg32_reg32(rd1, rt1);
   mov_reg32_reg32(rd2, rt2);
   shrd_reg32_reg32_imm8(rd1, rd2, dst->f.r.sa);
   sar_reg32_imm8(rd2, dst->f.r.sa);
   if (dst->f.r.sa & 0x20)
     {
    mov_reg32_reg32(rd1, rd2);
    sar_reg32_imm8(rd2, 31);
     }
#endif
}
Beispiel #4
0
void gendsrl(void)
{
#ifdef INTERPRET_DSRL
   gencallinterp((unsigned int)cached_interpreter_table.DSRL, 0);
#else
   int rt1 = allocate_64_register1((unsigned int *)g_dev.r4300.recomp.dst->f.r.rt);
   int rt2 = allocate_64_register2((unsigned int *)g_dev.r4300.recomp.dst->f.r.rt);
   int rd1 = allocate_64_register1_w((unsigned int *)g_dev.r4300.recomp.dst->f.r.rd);
   int rd2 = allocate_64_register2_w((unsigned int *)g_dev.r4300.recomp.dst->f.r.rd);
   
   mov_reg32_reg32(rd1, rt1);
   mov_reg32_reg32(rd2, rt2);
   shrd_reg32_reg32_imm8(rd1, rd2, g_dev.r4300.recomp.dst->f.r.sa);
   shr_reg32_imm8(rd2, g_dev.r4300.recomp.dst->f.r.sa);
   if (g_dev.r4300.recomp.dst->f.r.sa & 0x20)
     {
    mov_reg32_reg32(rd1, rd2);
    xor_reg32_reg32(rd2, rd2);
     }
#endif
}
Beispiel #5
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
}
Beispiel #6
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
}
Beispiel #7
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
}
void gendadd(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[89]);
#endif
#ifdef INTERPRET_DADD
   gencallinterp((unsigned long long)cached_interpreter_table.DADD, 0);
#else
   int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
   int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
   int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);

   if (rs == rd)
     add_reg64_reg64(rd, rt);
   else if (rt == rd)
     add_reg64_reg64(rd, rs);
   else
     {
    mov_reg64_reg64(rd, rs);
    add_reg64_reg64(rd, rt);
     }
#endif
}
void genaddu(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[80]);
#endif
#ifdef INTERPRET_ADDU
   gencallinterp((unsigned long long)cached_interpreter_table.ADDU, 0);
#else
   int rs = allocate_register_32((unsigned int *)dst->f.r.rs);
   int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
   int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);

   if (rs == rd)
     add_reg32_reg32(rd, rt);
   else if (rt == rd)
     add_reg32_reg32(rd, rs);
   else
     {
    mov_reg32_reg32(rd, rs);
    add_reg32_reg32(rd, rt);
     }
#endif
}
Beispiel #10
0
void genmul_s(void)
{
#ifdef INTERPRET_MUL_S
   gencallinterp((native_type)cached_interpreter_table.MUL_S, 0);
#else
   gencheck_cop1_unusable();
#ifdef __x86_64__
   mov_xreg64_m64rel(RAX, (unsigned long long *)(&reg_cop1_simple[dst->f.cf.fs]));
   fld_preg64_dword(RAX);
   mov_xreg64_m64rel(RAX, (unsigned long long *)(&reg_cop1_simple[dst->f.cf.ft]));
   fmul_preg64_dword(RAX);
   mov_xreg64_m64rel(RAX, (unsigned long long *)(&reg_cop1_simple[dst->f.cf.fd]));
   fstp_preg64_dword(RAX);
#else
   mov_eax_memoffs32((unsigned int *)(&reg_cop1_simple[dst->f.cf.fs]));
   fld_preg32_dword(EAX);
   mov_eax_memoffs32((unsigned int *)(&reg_cop1_simple[dst->f.cf.ft]));
   fmul_preg32_dword(EAX);
   mov_eax_memoffs32((unsigned int *)(&reg_cop1_simple[dst->f.cf.fd]));
   fstp_preg32_dword(EAX);
#endif
#endif
}
Beispiel #11
0
void gendaddu(void)
{
#if defined(COUNT_INSTR)
   inc_m32abs(&instr_count[90]);
#endif
#ifdef INTERPRET_DADDU
   gencallinterp((unsigned long long)DADDU, 0);
#else
   int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
   int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
   int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);

   if (rs == rd)
     add_reg64_reg64(rd, rt);
   else if (rt == rd)
     add_reg64_reg64(rd, rs);
   else
     {
    mov_reg64_reg64(rd, rs);
    add_reg64_reg64(rd, rt);
     }
#endif
}
Beispiel #12
0
void genxor(void)
{
#if defined(COUNT_INSTR)
   inc_m32abs(&instr_count[85]);
#endif
#ifdef INTERPRET_XOR
   gencallinterp((unsigned long long)XOR, 0);
#else
   int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
   int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
   int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);

   if (rs == rd)
     xor_reg64_reg64(rd, rt);
   else if (rt == rd)
     xor_reg64_reg64(rd, rs);
   else
     {
    mov_reg64_reg64(rd, rs);
    xor_reg64_reg64(rd, rt);
     }
#endif
}
Beispiel #13
0
void genadd(void)
{
#if defined(COUNT_INSTR)
   inc_m32abs(&instr_count[79]);
#endif
#ifdef INTERPRET_ADD
   gencallinterp((unsigned long long)ADD, 0);
#else
   int rs = allocate_register_32((unsigned int *)dst->f.r.rs);
   int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
   int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);

   if (rs == rd)
     add_reg32_reg32(rd, rt);
   else if (rt == rd)
     add_reg32_reg32(rd, rs);
   else
     {
    mov_reg32_reg32(rd, rs);
    add_reg32_reg32(rd, rt);
     }
#endif
}
Beispiel #14
0
void genfloor_w_s(void)
{
#ifdef INTERPRET_FLOOR_W_S
   gencallinterp((native_type)cached_interpreter_table.FLOOR_W_S, 0);
#else
   gencheck_cop1_unusable();
#ifdef __x86_64__
   fldcw_m16rel((unsigned short*)&floor_mode);
   mov_xreg64_m64rel(RAX, (unsigned long long *)(&reg_cop1_simple[dst->f.cf.fs]));
   fld_preg64_dword(RAX);
   mov_xreg64_m64rel(RAX, (unsigned long long *)(&reg_cop1_simple[dst->f.cf.fd]));
   fistp_preg64_dword(RAX);
   fldcw_m16rel((unsigned short*)&rounding_mode);
#else
   fldcw_m16((unsigned short*)&floor_mode);
   mov_eax_memoffs32((unsigned int *)(&reg_cop1_simple[dst->f.cf.fs]));
   fld_preg32_dword(EAX);
   mov_eax_memoffs32((unsigned int *)(&reg_cop1_simple[dst->f.cf.fd]));
   fistp_preg32_dword(EAX);
   fldcw_m16((unsigned short*)&rounding_mode);
#endif
#endif
}
Beispiel #15
0
void gennor(void)
{
#ifdef INTERPRET_NOR
   gencallinterp((unsigned int)cached_interpreter_table.NOR, 0);
#else
   int rs1 = allocate_64_register1((unsigned int *)g_dev.r4300.recomp.dst->f.r.rs);
   int rs2 = allocate_64_register2((unsigned int *)g_dev.r4300.recomp.dst->f.r.rs);
   int rt1 = allocate_64_register1((unsigned int *)g_dev.r4300.recomp.dst->f.r.rt);
   int rt2 = allocate_64_register2((unsigned int *)g_dev.r4300.recomp.dst->f.r.rt);
   int rd1 = allocate_64_register1_w((unsigned int *)g_dev.r4300.recomp.dst->f.r.rd);
   int rd2 = allocate_64_register2_w((unsigned int *)g_dev.r4300.recomp.dst->f.r.rd);
   
   if (rt1 != rd1 && rs1 != rd1)
     {
    mov_reg32_reg32(rd1, rs1);
    mov_reg32_reg32(rd2, rs2);
    or_reg32_reg32(rd1, rt1);
    or_reg32_reg32(rd2, rt2);
    not_reg32(rd1);
    not_reg32(rd2);
     }
   else
     {
    int temp = lru_register();
    free_register(temp);
    mov_reg32_reg32(temp, rs1);
    or_reg32_reg32(temp, rt1);
    mov_reg32_reg32(rd1, temp);
    mov_reg32_reg32(temp, rs2);
    or_reg32_reg32(temp, rt2);
    mov_reg32_reg32(rd2, temp);
    not_reg32(rd1);
    not_reg32(rd2);
     }
#endif
}
Beispiel #16
0
void gennor()
{
#ifdef INTERPRET_NOR
   gencallinterp((unsigned long)NOR, 0);
#else
   int rs1 = allocate_64_register1((unsigned long *)dst->f.r.rs);
   int rs2 = allocate_64_register2((unsigned long *)dst->f.r.rs);
   int rt1 = allocate_64_register1((unsigned long *)dst->f.r.rt);
   int rt2 = allocate_64_register2((unsigned long *)dst->f.r.rt);
   int rd1 = allocate_64_register1_w((unsigned long *)dst->f.r.rd);
   int rd2 = allocate_64_register2_w((unsigned long *)dst->f.r.rd);
   
   if (rt1 != rd1 && rs1 != rd1)
     {
	mov_reg32_reg32(rd1, rs1);
	mov_reg32_reg32(rd2, rs2);
	or_reg32_reg32(rd1, rt1);
	or_reg32_reg32(rd2, rt2);
	not_reg32(rd1);
	not_reg32(rd2);
     }
   else
     {
	int temp = lru_register();
	free_register(temp);
	mov_reg32_reg32(temp, rs1);
	or_reg32_reg32(temp, rt1);
	mov_reg32_reg32(rd1, temp);
	mov_reg32_reg32(temp, rs2);
	or_reg32_reg32(temp, rt2);
	mov_reg32_reg32(rd2, temp);
	not_reg32(rd1);
	not_reg32(rd2);
     }
#endif
}
Beispiel #17
0
void gensubu(usf_state_t * state)
{
#ifdef INTERPRET_SUBU
   gencallinterp(state, (unsigned int)state->current_instruction_table.SUBU, 0);
#else
   int rs = allocate_register(state, (unsigned int *)state->dst->f.r.rs);
   int rt = allocate_register(state, (unsigned int *)state->dst->f.r.rt);
   int rd = allocate_register_w(state, (unsigned int *)state->dst->f.r.rd);
   
   if (rt != rd && rs != rd)
     {
    mov_reg32_reg32(state, rd, rs);
    sub_reg32_reg32(state, rd, rt);
     }
   else
     {
    int temp = lru_register(state);
    free_register(state, temp);
    mov_reg32_reg32(state, temp, rs);
    sub_reg32_reg32(state, temp, rt);
    mov_reg32_reg32(state, rd, temp);
     }
#endif
}
Beispiel #18
0
void gensubu()
{
#ifdef INTERPRET_SUBU
   gencallinterp((unsigned long)SUBU, 0);
#else
   int rs = allocate_register((unsigned long *)dst->f.r.rs);
   int rt = allocate_register((unsigned long *)dst->f.r.rt);
   int rd = allocate_register_w((unsigned long *)dst->f.r.rd);
   
   if (rt != rd && rs != rd)
     {
	mov_reg32_reg32(rd, rs);
	sub_reg32_reg32(rd, rt);
     }
   else
     {
	int temp = lru_register();
	free_register(temp);
	mov_reg32_reg32(temp, rs);
	sub_reg32_reg32(temp, rt);
	mov_reg32_reg32(rd, temp);
     }
#endif
}
Beispiel #19
0
void genaddu(void)
{
#ifdef INTERPRET_ADDU
   gencallinterp((unsigned int)cached_interpreter_table.ADDU, 0);
#else
   int rs = allocate_register((unsigned int *)g_dev.r4300.recomp.dst->f.r.rs);
   int rt = allocate_register((unsigned int *)g_dev.r4300.recomp.dst->f.r.rt);
   int rd = allocate_register_w((unsigned int *)g_dev.r4300.recomp.dst->f.r.rd);
   
   if (rt != rd && rs != rd)
     {
    mov_reg32_reg32(rd, rs);
    add_reg32_reg32(rd, rt);
     }
   else
     {
    int temp = lru_register();
    free_register(temp);
    mov_reg32_reg32(temp, rs);
    add_reg32_reg32(temp, rt);
    mov_reg32_reg32(rd, temp);
     }
#endif
}
Beispiel #20
0
void gennor(usf_state_t * state)
{
#ifdef INTERPRET_NOR
   gencallinterp(state, (unsigned int)state->current_instruction_table.NOR, 0);
#else
   int rs1 = allocate_64_register1(state, (unsigned int *)state->dst->f.r.rs);
   int rs2 = allocate_64_register2(state, (unsigned int *)state->dst->f.r.rs);
   int rt1 = allocate_64_register1(state, (unsigned int *)state->dst->f.r.rt);
   int rt2 = allocate_64_register2(state, (unsigned int *)state->dst->f.r.rt);
   int rd1 = allocate_64_register1_w(state, (unsigned int *)state->dst->f.r.rd);
   int rd2 = allocate_64_register2_w(state, (unsigned int *)state->dst->f.r.rd);
   
   if (rt1 != rd1 && rs1 != rd1)
     {
    mov_reg32_reg32(state, rd1, rs1);
    mov_reg32_reg32(state, rd2, rs2);
    or_reg32_reg32(state, rd1, rt1);
    or_reg32_reg32(state, rd2, rt2);
    not_reg32(state, rd1);
    not_reg32(state, rd2);
     }
   else
     {
    int temp = lru_register(state);
    free_register(state, temp);
    mov_reg32_reg32(state, temp, rs1);
    or_reg32_reg32(state, temp, rt1);
    mov_reg32_reg32(state, rd1, temp);
    mov_reg32_reg32(state, temp, rs2);
    or_reg32_reg32(state, temp, rt2);
    mov_reg32_reg32(state, rd2, temp);
    not_reg32(state, rd1);
    not_reg32(state, rd2);
     }
#endif
}
Beispiel #21
0
void gensub(void)
{
#ifdef INTERPRET_SUB
    gencallinterp((unsigned int)cached_interpreter_table.SUB, 0);
#else
    int rs = allocate_register((unsigned int *)dst->f.r.rs);
    int rt = allocate_register((unsigned int *)dst->f.r.rt);
    int rd = allocate_register_w((unsigned int *)dst->f.r.rd);

    if (rt != rd && rs != rd)
    {
        mov_reg32_reg32(rd, rs);
        sub_reg32_reg32(rd, rt);
    }
    else
    {
        int temp = lru_register();
        free_register(temp);
        mov_reg32_reg32(temp, rs);
        sub_reg32_reg32(temp, rt);
        mov_reg32_reg32(rd, temp);
    }
#endif
}
Beispiel #22
0
void generet(void)
{
   gencallinterp((native_type)cached_interpreter_table.ERET, 1);
}
Beispiel #23
0
void genddivu()
{
   gencallinterp((unsigned long)DDIVU, 0);
}
Beispiel #24
0
void gendmult()
{
   gencallinterp((unsigned long)DMULT, 0);
}
Beispiel #25
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
}
Beispiel #26
0
void genteq()
{
   gencallinterp((unsigned long)TEQ, 0);
}
Beispiel #27
0
void gendmult(void)
{
    gencallinterp((unsigned int)cached_interpreter_table.DMULT, 0);
}
Beispiel #28
0
void genddivu(void)
{
    gencallinterp((unsigned int)cached_interpreter_table.DDIVU, 0);
}
Beispiel #29
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
}
Beispiel #30
0
void gentlbwr(void)
{
   gencallinterp((native_type)cached_interpreter_table.TLBWR, 0);
}