void gennor(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[86]); #endif #ifdef INTERPRET_NOR gencallinterp((unsigned long long)cached_interpreter_table.NOR, 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) { or_reg64_reg64(rd, rt); not_reg64(rd); } else if (rt == rd) { or_reg64_reg64(rd, rs); not_reg64(rd); } else { mov_reg64_reg64(rd, rs); or_reg64_reg64(rd, rt); not_reg64(rd); } #endif }
void gensub(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[81]); #endif #ifdef INTERPRET_SUB gencallinterp((unsigned long long)cached_interpreter_table.SUB, 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) sub_reg32_reg32(rd, rt); else if (rt == rd) { neg_reg32(rd); add_reg32_reg32(rd, rs); } else { mov_reg32_reg32(rd, rs); sub_reg32_reg32(rd, rt); } #endif }
void genteq(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[96]); #endif gencallinterp((unsigned long long)cached_interpreter_table.TEQ, 0); }
void genmtc0(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[110]); #endif gencallinterp((unsigned long long)MTC0, 0); }
void genddivu(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[78]); #endif gencallinterp((unsigned long long)cached_interpreter_table.DDIVU, 0); }
void gendsrav(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[70]); #endif #ifdef INTERPRET_DSRAV gencallinterp((unsigned long long)cached_interpreter_table.DSRAV, 0); #else int rt, rd; allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register_64((unsigned long long *)dst->f.r.rt); rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd); if (rd != ECX) { mov_reg64_reg64(rd, rt); sar_reg64_cl(rd); } else { int temp; temp = lru_register(); free_register(temp); mov_reg64_reg64(temp, rt); sar_reg64_cl(temp); mov_reg64_reg64(rd, temp); } #endif }
void gendmult(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[75]); #endif gencallinterp((unsigned long long)cached_interpreter_table.DMULT, 0); }
void genctc1(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[116]); #endif #ifdef INTERPRET_CTC1 gencallinterp((unsigned long long)cached_interpreter_table.CTC1, 0); #else gencheck_cop1_unusable(); if (dst->f.r.nrd != 31) return; mov_xreg32_m32rel(EAX, (unsigned int*)dst->f.r.rt); mov_m32rel_xreg32((unsigned int*)&FCR31, EAX); and_eax_imm32(3); cmp_eax_imm32(0); jne_rj(13); mov_m32rel_imm32((unsigned int*)&rounding_mode, 0x33F); // 11 jmp_imm_short(51); // 2 cmp_eax_imm32(1); // 5 jne_rj(13); // 2 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0xF3F); // 11 jmp_imm_short(31); // 2 cmp_eax_imm32(2); // 5 jne_rj(13); // 2 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0xB3F); // 11 jmp_imm_short(11); // 2 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0x73F); // 11 fldcw_m16rel((unsigned short*)&rounding_mode); #endif }
void gendsubu(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[92]); #endif #ifdef INTERPRET_DSUBU gencallinterp((unsigned long long)cached_interpreter_table.DSUBU, 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) sub_reg64_reg64(rd, rt); else if (rt == rd) { neg_reg64(rd); add_reg64_reg64(rd, rs); } else { mov_reg64_reg64(rd, rs); sub_reg64_reg64(rd, rt); } #endif }
void gensllv(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[58]); #endif #ifdef INTERPRET_SLLV gencallinterp((unsigned long long)cached_interpreter_table.SLLV, 0); #else int rt, rd; allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register_32((unsigned int *)dst->f.r.rt); rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); if (rd != ECX) { mov_reg32_reg32(rd, rt); shl_reg32_cl(rd); } else { int temp = lru_register(); free_register(temp); mov_reg32_reg32(temp, rt); shl_reg32_cl(temp); mov_reg32_reg32(rd, temp); } #endif }
void genc_f_s(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[118]); #endif #ifdef INTERPRET_C_F_S gencallinterp((unsigned long long)cached_interpreter_table.C_F_S, 0); #else gencheck_cop1_unusable(); and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); #endif }
void genmtlo(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[67]); #endif #ifdef INTERPRET_MTLO gencallinterp((unsigned long long)cached_interpreter_table.MTLO, 0); #else int _lo = allocate_register_64_w((unsigned long long *)&lo); int rs = allocate_register_64((unsigned long long *)dst->f.r.rs); mov_reg64_reg64(_lo, rs); #endif }
void genmthi(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[65]); #endif #ifdef INTERPRET_MTHI gencallinterp((unsigned long long)cached_interpreter_table.MTHI, 0); #else int _hi = allocate_register_64_w((unsigned long long *) &hi); int rs = allocate_register_64((unsigned long long *) dst->f.r.rs); mov_reg64_reg64(_hi, rs); #endif }
void gensyscall(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[63]); #endif #ifdef INTERPRET_SYSCALL gencallinterp((unsigned long long)cached_interpreter_table.SYSCALL, 0); #else free_registers_move_start(); mov_m32rel_imm32(&g_cp0_regs[CP0_CAUSE_REG], 8 << 2); gencallinterp((unsigned long long)exception_general, 0); #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*)dst->f.r.rt); mov_xreg64_m64rel(RBX, (unsigned long long *)(®_cop1_simple[dst->f.r.nrd])); mov_preg64_reg32(RBX, EAX); #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 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 gendsrl(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[94]); #endif #ifdef INTERPRET_DSRL gencallinterp((unsigned long long)cached_interpreter_table.DSRL, 0); #else 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); mov_reg64_reg64(rd, rt); shr_reg64_imm8(rd, dst->f.r.sa); #endif }
void gensra(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[57]); #endif #ifdef INTERPRET_SRA gencallinterp((unsigned long long)cached_interpreter_table.SRA, 0); #else int rt = allocate_register_32((unsigned int *)dst->f.r.rt); int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd); mov_reg32_reg32(rd, rt); sar_reg32_imm8(rd, dst->f.r.sa); #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*)g_dev.r4300.recomp.dst->f.r.rt); mov_xreg32_m32rel(EBX, ((unsigned int*)g_dev.r4300.recomp.dst->f.r.rt)+1); mov_xreg64_m64rel(RDX, (unsigned long long *)(&(r4300_cp1_regs_double())[g_dev.r4300.recomp.dst->f.r.nrd])); mov_preg64_reg32(RDX, EAX); mov_preg64pimm32_reg32(RDX, 4, EBX); #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 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 genmult(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[71]); #endif #ifdef INTERPRET_MULT gencallinterp((unsigned long long)cached_interpreter_table.MULT, 0); #else int rs, rt; allocate_register_32_manually_w(EAX, (unsigned int *)&lo); /* these must be done first so they are not assigned by allocate_register() */ allocate_register_32_manually_w(EDX, (unsigned int *)&hi); rs = allocate_register_32((unsigned int*)dst->f.r.rs); rt = allocate_register_32((unsigned int*)dst->f.r.rt); mov_reg32_reg32(EAX, rs); imul_reg32(rt); #endif }
void genmultu(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[72]); #endif #ifdef INTERPRET_MULTU gencallinterp((unsigned long long)cached_interpreter_table.MULTU, 0); #else int rs, rt; allocate_register_32_manually_w(EAX, (unsigned int *)&lo); allocate_register_32_manually_w(EDX, (unsigned int *)&hi); rs = allocate_register_32((unsigned int*)dst->f.r.rs); rt = allocate_register_32((unsigned int*)dst->f.r.rt); mov_reg32_reg32(EAX, rs); mul_reg32(rt); #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 gendmultu(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[76]); #endif #ifdef INTERPRET_DMULTU gencallinterp((unsigned long long)cached_interpreter_table.DMULTU, 0); #else free_registers_move_start(); mov_xreg64_m64rel(RAX, (unsigned long long *) dst->f.r.rs); mov_xreg64_m64rel(RDX, (unsigned long long *) dst->f.r.rt); mul_reg64(RDX); mov_m64rel_xreg64((unsigned long long *) &lo, RAX); mov_m64rel_xreg64((unsigned long long *) &hi, RDX); #endif }
void gensltu(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[88]); #endif #ifdef INTERPRET_SLTU gencallinterp((unsigned long long)cached_interpreter_table.SLTU, 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); cmp_reg64_reg64(rs, rt); setb_reg8(rd); and_reg64_imm8(rd, 1); #endif }
void genc_sf_s(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[118]); #endif #ifdef INTERPRET_C_SF_S gencallinterp((unsigned long long)cached_interpreter_table.C_SF_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); fcomip_fpreg(1); ffree_fpreg(0); and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); #endif }
void genbltz_out(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[47]); #endif #ifdef INTERPRET_BLTZ_OUT gencallinterp((unsigned long long)BLTZ_OUT, 1); #else if (((dst->addr & 0xFFF) == 0xFFC && (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump) { gencallinterp((unsigned long long)BLTZ_OUT, 1); return; } genbltz_test(); gendelayslot(); gentest_out(); #endif }