static void genbltz_test(void) { int rs_64bit = is64((unsigned int *)dst->f.i.rs); if (!rs_64bit) { int rs = allocate_register((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs, 0); jge_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 } else if (rs_64bit == -1) { cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0); jge_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 } else { int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs2, 0); jge_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 } }
void genctc1(void) { #ifdef INTERPRET_CTC1 gencallinterp((unsigned int)CTC1, 0); #else gencheck_cop1_unusable(); if (dst->f.r.nrd != 31) return; mov_eax_memoffs32((unsigned int*)dst->f.r.rt); mov_memoffs32_eax((unsigned int*)&FCR31); and_eax_imm32(3); cmp_eax_imm32(0); jne_rj(12); mov_m32_imm32((unsigned int*)&rounding_mode, 0x33F); // 10 jmp_imm_short(48); // 2 cmp_eax_imm32(1); // 5 jne_rj(12); // 2 mov_m32_imm32((unsigned int*)&rounding_mode, 0xF3F); // 10 jmp_imm_short(29); // 2 cmp_eax_imm32(2); // 5 jne_rj(12); // 2 mov_m32_imm32((unsigned int*)&rounding_mode, 0xB3F); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int*)&rounding_mode, 0x73F); // 10 fldcw_m16((unsigned short*)&rounding_mode); #endif }
void genc_ngt_s(void) { #ifdef INTERPRET_C_NGT_S gencallinterp((native_type)cached_interpreter_table.C_NGT_S, 0); #else gencheck_cop1_unusable(); #ifdef __x86_64__ 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); jp_rj(15); ja_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #else mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jp_rj(14); ja_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif #endif }
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 }
static void genbltz_test(void) { int rs_64bit = is64((unsigned int *)dst->f.i.rs); if (rs_64bit == 0) { #ifdef __x86_64__ int rs = allocate_register_32((unsigned int *)dst->f.i.rs); #else int rs = allocate_register((unsigned int *)dst->f.i.rs); #endif cmp_reg32_imm32(rs, 0); #ifdef __x86_64__ setl_m8rel((unsigned char *) &branch_taken); #else jge_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } else if (rs_64bit == -1) { #ifdef __x86_64__ cmp_m32rel_imm32(((unsigned int *)dst->f.i.rs)+1, 0); setl_m8rel((unsigned char *) &branch_taken); #else cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0); jge_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } else { #ifdef __x86_64__ int rs = allocate_register_64((uint64_t*)dst->f.i.rs); cmp_reg64_imm8(rs, 0); setl_m8rel((unsigned char *) &branch_taken); #else int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs); cmp_reg32_imm32(rs2, 0); jge_rj(12); mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10 #endif } }
void genbc1f_test() { test_m32_imm32((u32*)&FCR31, 0x800000); jne_rj(12); mov_m32_imm32((u32*)(&branch_taken), 1); /* 10 */ jmp_imm_short(10); /* 2 */ mov_m32_imm32((u32*)(&branch_taken), 0); /* 10 */ }
static void genbc1t_test(void) { test_m32_imm32((unsigned int*)&(*r4300_cp1_fcr31()), 0x800000); je_rj(12); mov_m32_imm32((unsigned int*)(&g_dev.r4300.branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int*)(&g_dev.r4300.branch_taken), 0); // 10 }
void genbc1t_test(void) { test_m32_imm32((unsigned int*)&FCR31, 0x800000); je_rj(12); mov_m32_imm32((unsigned int*)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int*)(&branch_taken), 0); // 10 }
static void genbc1t_test(void) { #if defined(__x86_64__) test_m32rel_imm32((uint32_t*)&FCR31, 0x800000); setne_m8rel((uint8_t *) &branch_taken); #else test_m32_imm32((uint32_t*)&FCR31, 0x800000); je_rj(12); mov_m32_imm32((uint32_t*)(&branch_taken), 1); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((uint32_t*)(&branch_taken), 0); // 10 #endif }
void genctc1(void) { #ifdef INTERPRET_CTC1 gencallinterp((native_type)cached_interpreter_table.CTC1, 0); #else gencheck_cop1_unusable(); if (dst->f.r.nrd != 31) return; #ifdef __x86_64__ 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); #else mov_eax_memoffs32((unsigned int*)dst->f.r.rt); mov_memoffs32_eax((unsigned int*)&FCR31); and_eax_imm32(3); cmp_eax_imm32(0); jne_rj(12); mov_m32_imm32((unsigned int*)&rounding_mode, 0x33F); // 10 jmp_imm_short(48); // 2 cmp_eax_imm32(1); // 5 jne_rj(12); // 2 mov_m32_imm32((unsigned int*)&rounding_mode, 0xF3F); // 10 jmp_imm_short(29); // 2 cmp_eax_imm32(2); // 5 jne_rj(12); // 2 mov_m32_imm32((unsigned int*)&rounding_mode, 0xB3F); // 10 jmp_imm_short(10); // 2 mov_m32_imm32((unsigned int*)&rounding_mode, 0x73F); // 10 fldcw_m16((unsigned short*)&rounding_mode); #endif #endif }
void genc_le_s() { #ifdef INTERPRET_C_LE_S gencallinterp((u32)C_LE_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); ja_rj(12); or_m32_imm32((u32*)&FCR31, 0x800000); /* 10 */ jmp_imm_short(10); /* 2 */ and_m32_imm32((u32*)&FCR31, ~0x800000); /* 10 */ #endif }
void genc_le_d(usf_state_t * state) { #ifdef INTERPRET_C_LE_D gencallinterp(state, (unsigned int)state->current_instruction_table.C_LE_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); ja_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 genc_lt_s(void) { #ifdef INTERPRET_C_LT_S gencallinterp((unsigned int)C_LT_S, 0); #else gencheck_cop1_unusable(); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.ft])); fld_preg32_dword(EAX); mov_eax_memoffs32((unsigned int *)(®_cop1_simple[dst->f.cf.fs])); fld_preg32_dword(EAX); fcomip_fpreg(1); ffree_fpreg(0); jae_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif }
void genc_le_d() { #ifdef INTERPRET_C_LE_D gencallinterp((unsigned long)C_LE_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); ja_rj(12); // 2 or_m32_imm32((unsigned long*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned long*)&FCR31, ~0x800000); // 10 #endif }
void genc_ueq_d(void) { #ifdef INTERPRET_C_UEQ_D gencallinterp((unsigned int)C_UEQ_D, 0); #else gencheck_cop1_unusable(); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft])); fld_preg32_qword(EAX); mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs])); fld_preg32_qword(EAX); fucomip_fpreg(1); ffree_fpreg(0); jp_rj(14); jne_rj(12); or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10 jmp_imm_short(10); // 2 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10 #endif }
void gensltu() { #ifdef INTERPRET_SLTU gencallinterp((unsigned long)SLTU, 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 rd = allocate_register_w((unsigned long *)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 genslt(void) { #ifdef INTERPRET_SLT gencallinterp((unsigned int)cached_interpreter_table.SLT, 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); jl_rj(13); jne_rj(4); // 2 cmp_reg32_reg32(rs1, rt1); // 2 jl_rj(7); // 2 mov_reg32_imm32(rd, 0); // 5 jmp_imm_short(5); // 2 mov_reg32_imm32(rd, 1); // 5 #endif }
void gensltu(usf_state_t * state) { #ifdef INTERPRET_SLTU gencallinterp(state, (unsigned int)state->current_instruction_table.SLTU, 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 rd = allocate_register_w(state, (unsigned int *)state->dst->f.r.rd); cmp_reg32_reg32(state, rs2, rt2); jb_rj(state, 13); jne_rj(state, 4); // 2 cmp_reg32_reg32(state, rs1, rt1); // 2 jb_rj(state, 7); // 2 mov_reg32_imm32(state, rd, 0); // 5 jmp_imm_short(state, 5); // 2 mov_reg32_imm32(state, rd, 1); // 5 #endif }
void genc_le_s(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[118]); #endif #ifdef INTERPRET_C_LE_S gencallinterp((unsigned long long)cached_interpreter_table.C_LE_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); ja_rj(13); or_m32rel_imm32((unsigned int*)&FCR31, 0x800000); // 11 jmp_imm_short(11); // 2 and_m32rel_imm32((unsigned int*)&FCR31, ~0x800000); // 11 #endif }