int Interpreter::SingleStepInner() { static UGeckoInstruction instCode; u32 function = HLE::GetFunctionIndex(PC); if (function != 0) { int type = HLE::GetFunctionTypeByIndex(function); if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE) { int flags = HLE::GetFunctionFlagsByIndex(function); if (HLE::IsEnabled(flags)) { HLEFunction(function); if (type == HLE::HLE_HOOK_START) { // Run the original. function = 0; } } else { function = 0; } } } if (function == 0) { #ifdef USE_GDBSTUB if (gdb_active() && gdb_bp_x(PC)) { Host_UpdateDisasmDialog(); gdb_signal(SIGTRAP); gdb_handle_exception(); } #endif NPC = PC + sizeof(UGeckoInstruction); instCode.hex = PowerPC::Read_Opcode(PC); // Uncomment to trace the interpreter //if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624) // startTrace = 1; //else // startTrace = 0; if (startTrace) { Trace(instCode); } if (instCode.hex != 0) { UReg_MSR& msr = (UReg_MSR&)MSR; if (msr.FP) //If FPU is enabled, just execute { m_opTable[instCode.OPCD](instCode); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PowerPC::CheckExceptions(); m_EndBlock = true; } } else { // check if we have to generate a FPU unavailable exception if (!PPCTables::UsesFPU(instCode)) { m_opTable[instCode.OPCD](instCode); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PowerPC::CheckExceptions(); m_EndBlock = true; } } else { PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE; PowerPC::CheckExceptions(); m_EndBlock = true; } } } else { // Memory exception on instruction fetch PowerPC::CheckExceptions(); m_EndBlock = true; } } last_pc = PC; PC = NPC; GekkoOPInfo *opinfo = GetOpInfo(instCode); return opinfo->numCycles; }
int Interpreter::SingleStepInner() { if (HandleFunctionHooking(PC)) { UpdatePC(); return PPCTables::GetOpInfo(m_prev_inst)->numCycles; } #ifdef USE_GDBSTUB if (gdb_active() && gdb_bp_x(PC)) { Host_UpdateDisasmDialog(); gdb_signal(GDB_SIGTRAP); gdb_handle_exception(); } #endif NPC = PC + sizeof(UGeckoInstruction); m_prev_inst.hex = PowerPC::Read_Opcode(PC); // Uncomment to trace the interpreter // if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624) // startTrace = 1; // else // startTrace = 0; if (startTrace) { Trace(m_prev_inst); } if (m_prev_inst.hex != 0) { if (IsInvalidPairedSingleExecution(m_prev_inst)) { GenerateProgramException(); CheckExceptions(); } else if (MSR.FP) { m_op_table[m_prev_inst.OPCD](m_prev_inst); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { CheckExceptions(); } } else { // check if we have to generate a FPU unavailable exception or a program exception. if (PPCTables::UsesFPU(m_prev_inst)) { PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE; CheckExceptions(); } else { m_op_table[m_prev_inst.OPCD](m_prev_inst); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { CheckExceptions(); } } } } else { // Memory exception on instruction fetch CheckExceptions(); } UpdatePC(); return PPCTables::GetOpInfo(m_prev_inst)->numCycles; }
int Interpreter::SingleStepInner(void) { static UGeckoInstruction instCode; u32 function = m_EndBlock ? HLE::GetFunctionIndex(PC) : 0; // Check for HLE functions after branches if (function != 0) { int type = HLE::GetFunctionTypeByIndex(function); if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE) { int flags = HLE::GetFunctionFlagsByIndex(function); if (HLE::IsEnabled(flags)) { HLEFunction(function); if (type == HLE::HLE_HOOK_START) { // Run the original. function = 0; } } else { function = 0; } } } if (function == 0) { #ifdef USE_GDBSTUB if (gdb_active() && gdb_bp_x(PC)) { Host_UpdateDisasmDialog(); gdb_signal(SIGTRAP); gdb_handle_exception(); } #endif NPC = PC + sizeof(UGeckoInstruction); instCode.hex = Memory::Read_Opcode(PC); // Uncomment to trace the interpreter //if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624) // startTrace = 1; //else // startTrace = 0; if (startTrace) { Trace(instCode); } if (instCode.hex != 0) { UReg_MSR& msr = (UReg_MSR&)MSR; if (msr.FP) //If FPU is enabled, just execute { m_opTable[instCode.OPCD](instCode); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PowerPC::CheckExceptions(); m_EndBlock = true; } } else { // check if we have to generate a FPU unavailable exception if (!PPCTables::UsesFPU(instCode)) { m_opTable[instCode.OPCD](instCode); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PowerPC::CheckExceptions(); m_EndBlock = true; } } else { Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_FPU_UNAVAILABLE); PowerPC::CheckExceptions(); m_EndBlock = true; } } } else { // Memory exception on instruction fetch PowerPC::CheckExceptions(); m_EndBlock = true; } } last_pc = PC; PC = NPC; #if defined(_DEBUG) || defined(DEBUGFAST) if (PowerPC::ppcState.gpr[1] == 0) { WARN_LOG(POWERPC, "%i Corrupt stack", PowerPC::ppcState.DebugCount); } PowerPC::ppcState.DebugCount++; #endif patches(); GekkoOPInfo *opinfo = GetOpInfo(instCode); return opinfo->numCyclesMinusOne + 1; }
int Interpreter::SingleStepInner() { if (!HandleFunctionHooking(PC)) { #ifdef USE_GDBSTUB if (gdb_active() && gdb_bp_x(PC)) { Host_UpdateDisasmDialog(); gdb_signal(SIGTRAP); gdb_handle_exception(); } #endif NPC = PC + sizeof(UGeckoInstruction); m_prev_inst.hex = PowerPC::Read_Opcode(PC); // Uncomment to trace the interpreter // if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624) // startTrace = 1; // else // startTrace = 0; if (startTrace) { Trace(m_prev_inst); } if (m_prev_inst.hex != 0) { if (MSR.FP) // If FPU is enabled, just execute { m_op_table[m_prev_inst.OPCD](m_prev_inst); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PowerPC::CheckExceptions(); m_end_block = true; } } else { // check if we have to generate a FPU unavailable exception if (!PPCTables::UsesFPU(m_prev_inst)) { m_op_table[m_prev_inst.OPCD](m_prev_inst); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PowerPC::CheckExceptions(); m_end_block = true; } } else { PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE; PowerPC::CheckExceptions(); m_end_block = true; } } } else { // Memory exception on instruction fetch PowerPC::CheckExceptions(); m_end_block = true; } } last_pc = PC; PC = NPC; const GekkoOPInfo* opinfo = PPCTables::GetOpInfo(m_prev_inst); return opinfo->numCycles; }