void r4300_execute(void) { if (r4300emu == CORE_PURE_INTERPRETER) { while (!stop) pure_interpreter(); } else if (r4300emu == CORE_INTERPRETER) { while (!stop) { #ifdef COMPARE_CORE if (PC->ops == cached_interpreter_table.FIN_BLOCK && (PC->addr < 0x80000000 || PC->addr >= 0xc0000000)) virtual_to_physical_address(PC->addr, 2); CoreCompareCallback(); #endif #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); } } #if defined(DYNAREC) else if (r4300emu >= 2) { #ifdef NEW_DYNAREC new_dyna_start(); #else dyna_start(dyna_jump); #endif } #endif }
void BGEZALL_OUT(void) { local_rs = irs; reg[31]=PC->addr+8; if((&irs)!=(reg+31)) { if (local_rs >= 0) { jump_target = (int)PC->f.i.immediate; PC++; delay_slot=1; #ifdef DBG if (debugger_mode) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if (!skip_jump) jump_to(PC->addr + ((jump_target-1)<<2)); } else PC+=2; } else printf("erreur dans bgezall\n"); last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void pure_interpreter(void) { stop=0; PC = &interp_PC; PC->addr = last_addr = 0xa4000040; /*#ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif*/ current_instruction_table = pure_interpreter_table; while (!stop) { prefetch(); #ifdef COMPARE_CORE CoreCompareCallback(); #endif #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); } }
void BLTZALL(void) { local_rs = irs; reg[31]=PC->addr+8; if((&irs)!=(reg+31)) { if (local_rs < 0) { PC++; delay_slot=1; #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if(!skip_jump) PC += (PC-2)->f.i.immediate-1; } else PC+=2; } else DebugMessage(M64MSG_ERROR, "error in BLTZALL"); last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void BGEZALL_OUT(void) { local_rs = irs; reg[31]=PC->addr+8; if((&irs)!=(reg+31)) { if (local_rs >= 0) { jump_target = (int)PC->f.i.immediate; PC++; delay_slot=1; #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if (!skip_jump) jump_to(PC->addr + ((jump_target-1)<<2)); } else PC+=2; } else DebugMessage(M64MSG_ERROR, "error in BGEZALL_OUT"); last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void BLTZALL(void) { local_rs = irs; reg[31]=PC->addr+8; if((&irs)!=(reg+31)) { if (local_rs < 0) { PC++; delay_slot=1; #ifdef DBG if (debugger_mode) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if(!skip_jump) PC += (PC-2)->f.i.immediate-1; } else PC+=2; } else printf("erreur dans bltzall\n"); last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
static void pc_ops_wrapper(void) { #ifdef COMPARE_CORE if (PC->ops == cached_interpreter_table.FIN_BLOCK && (PC->addr < 0x80000000 || PC->addr >= 0xc0000000)) virtual_to_physical_address(PC->addr, TLB_FAST_READ); CoreCompareCallback(); #endif #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); }
// ----------------------------------------------------------- // Flow control 'fake' instructions // ----------------------------------------------------------- static void FIN_BLOCK(void) { if (!delay_slot) { jump_to((PC-1)->addr+4); #if 0 #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif // Used by dynarec only, check should be unnecessary #endif PC->ops(); if (r4300emu == CORE_DYNAREC) dyna_jump(); } else { precomp_block *blk = actual; precomp_instr *inst = PC; jump_to((PC-1)->addr+4); #if 0 #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif // Used by dynarec only, check should be unnecessary #endif PC->ops(); if (!skip_jump) { actual = blk; PC = inst+1; } if (r4300emu == CORE_DYNAREC) dyna_jump(); } }
void J(void) { PC++; delay_slot=1; #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if (!skip_jump) PC=actual->block+ (((((PC-2)->f.j.inst_index<<2) | ((PC-1)->addr & 0xF0000000))-actual->start)>>2); last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void BC1T(void) { if (check_cop1_unusable()) return; PC++; delay_slot=1; #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if ((FCR31 & 0x800000)!=0 && !skip_jump) PC += (PC-2)->f.i.immediate-1; last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void J_OUT(void) { jump_target = (PC->addr & 0xF0000000) | (PC->f.j.inst_index<<2); PC++; delay_slot=1; #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if (!skip_jump) jump_to(jump_target); last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void BGEZ(void) { local_rs = irs; PC++; delay_slot=1; #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if (local_rs >= 0 && !skip_jump) PC += (PC-2)->f.i.immediate - 1; last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void BC1T_OUT(void) { if (check_cop1_unusable()) return; jump_target = (int)PC->f.i.immediate; PC++; delay_slot=1; #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if (!skip_jump && (FCR31 & 0x800000)!=0) jump_to(PC->addr + ((jump_target-1)<<2)); last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void BLTZ_OUT(void) { local_rs = irs; jump_target = (int)PC->f.i.immediate; PC++; delay_slot=1; #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if (!skip_jump && local_rs < 0) jump_to(PC->addr + ((jump_target-1)<<2)); last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void JAL(void) { PC++; delay_slot=1; #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if (!skip_jump) { reg[31]=PC->addr; sign_extended(reg[31]); PC=actual->block+ (((((PC-2)->f.j.inst_index<<2) | ((PC-1)->addr & 0xF0000000))-actual->start)>>2); }
void BGEZL(void) { if (irs >= 0) { PC++; delay_slot=1; #ifdef DBG if (debugger_mode) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if(!skip_jump) PC += (PC-2)->f.i.immediate-1; } else PC+=2; last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void BGEZL_OUT(void) { if (irs >= 0) { jump_target = (int)PC->f.i.immediate; PC++; delay_slot=1; #ifdef DBG if (debugger_mode) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if (!skip_jump) jump_to(PC->addr + ((jump_target-1)<<2)); } else PC+=2; last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void BC1TL(void) { if (check_cop1_unusable()) return; if ((FCR31 & 0x800000)!=0) { PC++; delay_slot=1; #ifdef DBG if (debugger_mode) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if(!skip_jump) PC += (PC-2)->f.i.immediate-1; } else { PC+=2; update_count(); } last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void BC1FL_OUT(void) { if (check_cop1_unusable()) return; if ((FCR31 & 0x800000)==0) { jump_target = (int)PC->f.i.immediate; PC++; delay_slot=1; #ifdef DBG if (debugger_mode) update_debugger(PC->addr); #endif PC->ops(); update_count(); delay_slot=0; if (!skip_jump) jump_to(PC->addr + ((jump_target-1)<<2)); } else { PC+=2; update_count(); } last_addr = PC->addr; if (next_interupt <= Count) gen_interupt(); }
void r4300_execute(void) { #if (defined(DYNAREC) && defined(PROFILE_R4300)) unsigned int i; #endif current_instruction_table = cached_interpreter_table; delay_slot=0; stop = 0; rompause = 0; /* clear instruction counters */ #if defined(COUNT_INSTR) memset(instr_count, 0, 131*sizeof(instr_count[0])); #endif last_addr = 0xa4000040; next_interupt = 624999; init_interupt(); if (r4300emu == CORE_PURE_INTERPRETER) { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Pure Interpreter"); r4300emu = CORE_PURE_INTERPRETER; pure_interpreter(); } #if defined(DYNAREC) else if (r4300emu >= 2) { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Dynamic Recompiler"); r4300emu = CORE_DYNAREC; init_blocks(); #ifdef NEW_DYNAREC new_dynarec_init(); new_dyna_start(); new_dynarec_cleanup(); #else dyna_start(dynarec_setup_code); PC++; #endif #if defined(PROFILE_R4300) pfProfile = fopen("instructionaddrs.dat", "ab"); for (i=0; i<0x100000; i++) if (invalid_code[i] == 0 && blocks[i] != NULL && blocks[i]->code != NULL && blocks[i]->block != NULL) { unsigned char *x86addr; int mipsop; // store final code length for this block mipsop = -1; /* -1 == end of x86 code block */ x86addr = blocks[i]->code + blocks[i]->code_length; if (fwrite(&mipsop, 1, 4, pfProfile) != 4 || fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *)) DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data"); } fclose(pfProfile); pfProfile = NULL; #endif free_blocks(); } #endif else /* if (r4300emu == CORE_INTERPRETER) */ { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Cached Interpreter"); r4300emu = CORE_INTERPRETER; init_blocks(); jump_to(0xa4000040); /* Prevent segfault on failed jump_to */ if (!actual->block) return; last_addr = PC->addr; while (!stop) { #ifdef COMPARE_CORE if (PC->ops == cached_interpreter_table.FIN_BLOCK && (PC->addr < 0x80000000 || PC->addr >= 0xc0000000)) virtual_to_physical_address(PC->addr, 2); CoreCompareCallback(); #endif #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); } free_blocks(); } DebugMessage(M64MSG_INFO, "R4300 emulator finished."); /* print instruction counts */ #if defined(COUNT_INSTR) if (r4300emu == CORE_DYNAREC) instr_counters_print(); #endif }