void genround_l_d(void) { #ifdef INTERPRET_ROUND_L_D gencallinterp((unsigned int)ROUND_L_D, 0); #else gencheck_cop1_unusable(); fldcw_m16((unsigned short*)&round_mode); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); fldcw_m16((unsigned short*)&rounding_mode); #endif }
void genmtc1(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[114]); #endif #ifdef INTERPRET_MTC1 gencallinterp((unsigned long long)cached_interpreter_table.MTC1, 0); #else gencheck_cop1_unusable(); mov_xreg32_m32rel(EAX, (unsigned int*)g_dev.r4300.recomp.dst->f.r.rt); mov_xreg64_m64rel(RBX, (unsigned long long *)(&(r4300_cp1_regs_simple())[g_dev.r4300.recomp.dst->f.r.nrd])); mov_preg64_reg32(RBX, EAX); #endif }
void genround_l_d(usf_state_t * state) { #ifdef INTERPRET_ROUND_L_D gencallinterp(state, (unsigned int)state->current_instruction_table.ROUND_L_D, 0); #else gencheck_cop1_unusable(state); fldcw_m16(state, (unsigned short*)&state->round_mode); mov_eax_memoffs32(state, (unsigned int*)(&state->reg_cop1_double[state->dst->f.cf.fs])); fld_preg32_qword(state, EAX); mov_eax_memoffs32(state, (unsigned int*)(&state->reg_cop1_double[state->dst->f.cf.fd])); fistp_preg32_qword(state, EAX); fldcw_m16(state, (unsigned short*)&state->rounding_mode); #endif }
void gensub_s(void) { #ifdef INTERPRET_SUB_S gencallinterp((unsigned int)SUB_S, 0); #else gencheck_cop1_unusable(); 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])); fsub_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif }
void genmul_d(void) { #ifdef INTERPRET_MUL_D gencallinterp((unsigned int)MUL_D, 0); #else gencheck_cop1_unusable(); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft])); fmul_preg32_qword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif }
void genmov_d(usf_state_t * state) { #ifdef INTERPRET_MOV_D gencallinterp(state, (unsigned int)state->current_instruction_table.MOV_D, 0); #else gencheck_cop1_unusable(state); mov_eax_memoffs32(state, (unsigned int *)(&state->reg_cop1_double[state->dst->f.cf.fs])); mov_reg32_preg32(state, EBX, EAX); mov_reg32_preg32pimm32(state, ECX, EAX, 4); mov_eax_memoffs32(state, (unsigned int *)(&state->reg_cop1_double[state->dst->f.cf.fd])); mov_preg32_reg32(state, EAX, EBX); mov_preg32pimm32_reg32(state, EAX, 4, ECX); #endif }
void genceil_l_s() { #ifdef INTERPRET_CEIL_L_S gencallinterp((u32)CEIL_L_S, 0); #else gencheck_cop1_unusable(); fldcw_m16((unsigned short*)&ceil_mode); mov_eax_memoffs32((u32 *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((u32 *)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); fldcw_m16((unsigned short*)&rounding_mode); #endif }
void genceil_w_s(void) { #ifdef INTERPRET_CEIL_W_S gencallinterp((unsigned int)cached_interpreter_table.CEIL_W_S, 0); #else gencheck_cop1_unusable(); fldcw_m16((unsigned short*)&ceil_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 }
void gendiv_d() { #ifdef INTERPRET_DIV_D gencallinterp((unsigned long)DIV_D, 0); #else gencheck_cop1_unusable(); mov_eax_memoffs32((unsigned long *)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned long *)(®_cop1_double[dst->f.cf.ft])); fdiv_preg32_qword(EAX); mov_eax_memoffs32((unsigned long *)(®_cop1_double[dst->f.cf.fd])); fstp_preg32_qword(EAX); #endif }
void gendiv_s(void) { #ifdef INTERPRET_DIV_S gencallinterp((unsigned int)cached_interpreter_table.DIV_S, 0); #else gencheck_cop1_unusable(); 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])); fdiv_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif }
void gentrunc_w_d() { #ifdef INTERPRET_TRUNC_W_D gencallinterp((unsigned long)TRUNC_W_D, 0); #else gencheck_cop1_unusable(); fldcw_m16((unsigned short*)&trunc_mode); mov_eax_memoffs32((unsigned long*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned long*)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); fldcw_m16((unsigned short*)&rounding_mode); #endif }
void genfloor_l_d() { #ifdef INTERPRET_FLOOR_L_D gencallinterp((unsigned long)FLOOR_L_D, 0); #else gencheck_cop1_unusable(); fldcw_m16((unsigned short*)&floor_mode); mov_eax_memoffs32((unsigned long*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned long*)(®_cop1_double[dst->f.cf.fd])); fistp_preg32_qword(EAX); fldcw_m16((unsigned short*)&rounding_mode); #endif }
void genmov_d() { #ifdef INTERPRET_MOV_D gencallinterp((unsigned long)MOV_D, 0); #else gencheck_cop1_unusable(); mov_eax_memoffs32((unsigned long *)(®_cop1_double[dst->f.cf.fs])); mov_reg32_preg32(EBX, EAX); mov_reg32_preg32pimm32(ECX, EAX, 4); mov_eax_memoffs32((unsigned long *)(®_cop1_double[dst->f.cf.fd])); mov_preg32_reg32(EAX, EBX); mov_preg32pimm32_reg32(EAX, 4, ECX); #endif }
void gendiv_s() { #ifdef INTERPRET_DIV_S gencallinterp((u32)DIV_S, 0); #else gencheck_cop1_unusable(); mov_eax_memoffs32((u32 *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((u32 *)(®_cop1_simple[dst->f.cf.ft])); fdiv_preg32_dword(EAX); mov_eax_memoffs32((u32 *)(®_cop1_simple[dst->f.cf.fd])); fstp_preg32_dword(EAX); #endif }
void genfloor_w_s() { #ifdef INTERPRET_FLOOR_W_S gencallinterp((u32)FLOOR_W_S, 0); #else gencheck_cop1_unusable(); fldcw_m16((unsigned short*)&floor_mode); mov_eax_memoffs32((u32 *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); mov_eax_memoffs32((u32 *)(®_cop1_simple[dst->f.cf.fd])); fistp_preg32_dword(EAX); fldcw_m16((unsigned short*)&rounding_mode); #endif }
void genc_sf_d() { #ifdef INTERPRET_C_SF_D gencallinterp((unsigned long)C_SF_D, 0); #else gencheck_cop1_unusable(); mov_eax_memoffs32((unsigned long*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned long*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fcomip_fpreg(1); ffree_fpreg(0); and_m32_imm32((unsigned long*)&FCR31, ~0x800000); #endif }
void genmov_s(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[125]); #endif #ifdef INTERPRET_MOV_S gencallinterp((unsigned long long)cached_interpreter_table.MOV_S, 0); #else gencheck_cop1_unusable(); mov_xreg64_m64rel(RAX, (unsigned long long *)(®_cop1_simple[dst->f.cf.fs])); mov_reg32_preg64(EBX, RAX); mov_xreg64_m64rel(RAX, (unsigned long long *)(®_cop1_simple[dst->f.cf.fd])); mov_preg64_reg32(RAX, EBX); #endif }
void genc_sf_s() { #ifdef INTERPRET_C_SF_S gencallinterp((u32)C_SF_S, 0); #else gencheck_cop1_unusable(); mov_eax_memoffs32((u32 *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((u32 *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fcomip_fpreg(1); ffree_fpreg(0); and_m32_imm32((u32*)&FCR31, ~0x800000); #endif }
void gencvt_l_s(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[117]); #endif #ifdef INTERPRET_CVT_L_S gencallinterp((unsigned long long)cached_interpreter_table.CVT_L_S, 0); #else gencheck_cop1_unusable(); 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_double[dst->f.cf.fd])); fistp_preg64_qword(RAX); #endif }
void gencvt_d_l(void) { #if defined(COUNT_INSTR) inc_m32abs(&instr_count[117]); #endif #ifdef INTERPRET_CVT_D_L gencallinterp((unsigned long long)CVT_D_L, 0); #else gencheck_cop1_unusable(); mov_reg64_m64abs(RAX, (unsigned long long *)(®_cop1_double[dst->f.cf.fs])); fild_preg64_qword(RAX); mov_reg64_m64abs(RAX, (unsigned long long *)(®_cop1_double[dst->f.cf.fd])); fstp_preg64_qword(RAX); #endif }
void genc_sf_d(usf_state_t * state) { #ifdef INTERPRET_C_SF_D gencallinterp(state, (unsigned int)state->current_instruction_table.C_SF_D, 0); #else gencheck_cop1_unusable(state); mov_eax_memoffs32(state, (unsigned int*)(&state->reg_cop1_double[state->dst->f.cf.ft])); fld_preg32_qword(state, EAX); mov_eax_memoffs32(state, (unsigned int*)(&state->reg_cop1_double[state->dst->f.cf.fs])); fld_preg32_qword(state, EAX); fcomip_fpreg(state, 1); ffree_fpreg(state, 0); and_m32_imm32(state, (unsigned int*)&state->FCR31, ~0x800000); #endif }
void gencfc1(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[113]); #endif #ifdef INTERPRET_CFC1 gencallinterp((unsigned long long)cached_interpreter_table.CFC1, 0); #else gencheck_cop1_unusable(); if(dst->f.r.nrd == 31) mov_xreg32_m32rel(EAX, (unsigned int*)&FCR31); else mov_xreg32_m32rel(EAX, (unsigned int*)&FCR0); mov_m32rel_xreg32((unsigned int*)dst->f.r.rt, EAX); sar_reg32_imm8(EAX, 31); mov_m32rel_xreg32(((unsigned int*)dst->f.r.rt)+1, EAX); #endif }
void gendmfc1(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[112]); #endif #ifdef INTERPRET_DMFC1 gencallinterp((unsigned long long)cached_interpreter_table.DMFC1, 0); #else gencheck_cop1_unusable(); mov_xreg64_m64rel(RAX, (unsigned long long *) (®_cop1_double[dst->f.r.nrd])); mov_reg32_preg64(EBX, RAX); mov_reg32_preg64pimm32(ECX, RAX, 4); mov_m32rel_xreg32((unsigned int*)dst->f.r.rt, EBX); mov_m32rel_xreg32(((unsigned int*)dst->f.r.rt)+1, ECX); #endif }
void gendmtc1(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[115]); #endif #ifdef INTERPRET_DMTC1 gencallinterp((unsigned long long)cached_interpreter_table.DMTC1, 0); #else gencheck_cop1_unusable(); mov_xreg32_m32rel(EAX, (unsigned int*)dst->f.r.rt); mov_xreg32_m32rel(EBX, ((unsigned int*)dst->f.r.rt)+1); mov_xreg64_m64rel(RDX, (unsigned long long *)(®_cop1_double[dst->f.r.nrd])); mov_preg64_reg32(RDX, EAX); mov_preg64pimm32_reg32(RDX, 4, EBX); #endif }
void genmfc1(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[111]); #endif #ifdef INTERPRET_MFC1 gencallinterp((unsigned long long)cached_interpreter_table.MFC1, 0); #else gencheck_cop1_unusable(); mov_xreg64_m64rel(RAX, (unsigned long long *)(&(r4300_cp1_regs_simple())[g_dev.r4300.recomp.dst->f.r.nrd])); mov_reg32_preg64(EBX, RAX); mov_m32rel_xreg32((unsigned int*)g_dev.r4300.recomp.dst->f.r.rt, EBX); sar_reg32_imm8(EBX, 31); mov_m32rel_xreg32(((unsigned int*)g_dev.r4300.recomp.dst->f.r.rt)+1, EBX); #endif }
void genmtc1(void) { #ifdef INTERPRET_MTC1 gencallinterp((native_type)cached_interpreter_table.MTC1, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ mov_xreg32_m32rel(EAX, (unsigned int*)dst->f.r.rt); mov_xreg64_m64rel(RBX, (unsigned long long *)(®_cop1_simple[dst->f.r.nrd])); mov_preg64_reg32(RBX, EAX); #else mov_eax_memoffs32((unsigned int*)dst->f.r.rt); mov_reg32_m32(EBX, (unsigned int*)(®_cop1_simple[dst->f.r.nrd])); mov_preg32_reg32(EBX, EAX); #endif #endif }
void genfloor_w_s(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[130]); #endif #ifdef INTERPRET_FLOOR_W_S gencallinterp((unsigned long long)cached_interpreter_table.FLOOR_W_S, 0); #else gencheck_cop1_unusable(); 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); #endif }
void genc_olt_d(usf_state_t * state) { #ifdef INTERPRET_C_OLT_D gencallinterp(state, (unsigned int)state->current_instruction_table.C_OLT_D, 0); #else gencheck_cop1_unusable(state); mov_eax_memoffs32(state, (unsigned int*)(&state->reg_cop1_double[state->dst->f.cf.ft])); fld_preg32_qword(state, EAX); mov_eax_memoffs32(state, (unsigned int*)(&state->reg_cop1_double[state->dst->f.cf.fs])); fld_preg32_qword(state, EAX); fucomip_fpreg(state, 1); ffree_fpreg(state, 0); jae_rj(state, 12); // 2 or_m32_imm32(state, (unsigned int*)&state->FCR31, 0x800000); // 10 jmp_imm_short(state, 10); // 2 and_m32_imm32(state, (unsigned int*)&state->FCR31, ~0x800000); // 10 #endif }
void genbc1f_idle(void) { #ifdef INTERPRET_BC1F_IDLE gencallinterp((unsigned int)BC1F_IDLE, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((unsigned int)BC1F_IDLE, 1); return; } gencheck_cop1_unusable(); genbc1f_test(); gentest_idle(); genbc1f(); #endif }
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 }