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 }
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 *)(®_cop1_simple[dst->f.cf.ft])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (unsigned long long *)(®_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 }
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 }
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 }
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 }
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 }
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 *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (unsigned long long *)(®_cop1_simple[dst->f.cf.ft])); fmul_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (unsigned long long *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg64_dword(RAX); #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fmul_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif #endif }
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 }
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 }
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 }
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 *)(®_cop1_simple[dst->f.cf.fs])); fld_preg64_dword(RAX); mov_xreg64_m64rel(RAX, (unsigned long long *)(®_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 *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); fldcw_m16((unsigned short*)&rounding_mode); #endif #endif }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
void generet(void) { gencallinterp((native_type)cached_interpreter_table.ERET, 1); }
void genddivu() { gencallinterp((unsigned long)DDIVU, 0); }
void gendmult() { gencallinterp((unsigned long)DMULT, 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 }
void genteq() { gencallinterp((unsigned long)TEQ, 0); }
void gendmult(void) { gencallinterp((unsigned int)cached_interpreter_table.DMULT, 0); }
void genddivu(void) { gencallinterp((unsigned int)cached_interpreter_table.DDIVU, 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 }
void gentlbwr(void) { gencallinterp((native_type)cached_interpreter_table.TLBWR, 0); }