diff --git a/Source/Core/Core/Src/Boot/Boot.cpp b/Source/Core/Core/Src/Boot/Boot.cpp index 522fdc6870..cf67b41f58 100644 --- a/Source/Core/Core/Src/Boot/Boot.cpp +++ b/Source/Core/Core/Src/Boot/Boot.cpp @@ -269,7 +269,7 @@ bool CBoot::BootUp(const SCoreStartupParameter& _StartupPara) Boot_ELF(_StartupPara.m_strFilename.c_str()); UpdateDebugger_MapLoaded(); - CBreakPoints::AddAutoBreakpoints(); + BreakPoints::AddAutoBreakpoints(); } break; diff --git a/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp b/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp index e4e5ae4247..ecf969c7b5 100644 --- a/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp +++ b/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp @@ -31,14 +31,9 @@ #include "../PowerPC/Jit64/Jit.h" #include "Debugger_BreakPoints.h" -CBreakPoints::TBreakPoints CBreakPoints::m_BreakPoints; -CBreakPoints::TMemChecks CBreakPoints::m_MemChecks; -u32 CBreakPoints::m_iBreakOnCount = 0; +BreakPoints::TBreakPoints BreakPoints::m_BreakPoints; -TMemCheck::TMemCheck() -{ - numHits = 0; -} +MemChecks::TMemChecks MemChecks::m_MemChecks; void TMemCheck::Action(u32 iValue, u32 addr, bool write, int size, u32 pc) { @@ -57,7 +52,7 @@ void TMemCheck::Action(u32 iValue, u32 addr, bool write, int size, u32 pc) } } -bool CBreakPoints::IsAddressBreakPoint(u32 _iAddress) +bool BreakPoints::IsAddressBreakPoint(u32 _iAddress) { std::vector::iterator iter; @@ -68,7 +63,7 @@ bool CBreakPoints::IsAddressBreakPoint(u32 _iAddress) return false; } -bool CBreakPoints::IsTempBreakPoint(u32 _iAddress) +bool BreakPoints::IsTempBreakPoint(u32 _iAddress) { std::vector::iterator iter; @@ -79,7 +74,82 @@ bool CBreakPoints::IsTempBreakPoint(u32 _iAddress) return false; } -TMemCheck *CBreakPoints::GetMemCheck(u32 address) +void BreakPoints::Add(u32 em_address, bool temp) +{ + if (!IsAddressBreakPoint(em_address)) // only add new addresses + { + TBreakPoint pt; // breakpoint settings + pt.bOn = true; + pt.bTemporary = temp; + pt.iAddress = em_address; + + m_BreakPoints.push_back(pt); + // jit.NotifyBreakpoint(em_address, true); + } +} + +void BreakPoints::Remove(u32 _iAddress) +{ + std::vector::iterator iter; + + for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter) + { + if ((*iter).iAddress == _iAddress) + { + m_BreakPoints.erase(iter); + // jit.NotifyBreakpoint(em_address, false); + break; + } + } +} + +void BreakPoints::Clear() +{ + m_BreakPoints.clear(); + Host_UpdateBreakPointView(); +} + +void BreakPoints::AddAutoBreakpoints() +{ +#if defined(_DEBUG) || defined(DEBUGFAST) +#if 1 + const char *bps[] = { + "PPCHalt", + }; + + for (int i = 0; i < sizeof(bps) / sizeof(const char *); i++) + { + Symbol *symbol = g_symbolDB.GetSymbolFromName(bps[i]); + if (symbol) + AddBreakPoint(symbol->address, false); + } +#endif +#endif +} + +void BreakPoints::DeleteByAddress(u32 _Address) +{ + // first check breakpoints + { + std::vector::iterator iter; + for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter) + { + if ((*iter).iAddress == _Address) + { + m_BreakPoints.erase(iter); + return; + } + } + } +} + +void MemChecks::Add(const TMemCheck& _rMemoryCheck) +{ + m_MemChecks.push_back(_rMemoryCheck); +} + + +TMemCheck *MemChecks::GetMemCheck(u32 address) { std::vector::iterator iter; for (iter = m_MemChecks.begin(); iter != m_MemChecks.end(); ++iter) @@ -100,89 +170,13 @@ TMemCheck *CBreakPoints::GetMemCheck(u32 address) return 0; } -void CBreakPoints::AddBreakPoint(u32 em_address, bool temp) +void MemChecks::Clear() { - if (!IsAddressBreakPoint(em_address)) // only add new addresses - { - TBreakPoint pt; // breakpoint settings - pt.bOn = true; - pt.bTemporary = temp; - pt.iAddress = em_address; - - m_BreakPoints.push_back(pt); - // jit.NotifyBreakpoint(em_address, true); - } -} - -void CBreakPoints::RemoveBreakPoint(u32 _iAddress) -{ - std::vector::iterator iter; - - for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter) - { - if ((*iter).iAddress == _iAddress) - { - m_BreakPoints.erase(iter); - // jit.NotifyBreakpoint(em_address, false); - break; - } - } -} - -void CBreakPoints::ClearAllBreakPoints() -{ - m_BreakPoints.clear(); m_MemChecks.clear(); - Host_UpdateBreakPointView(); } -// update breakpoint window -void CBreakPoints::UpdateBreakPointView() +void MemChecks::DeleteByAddress(u32 _Address) { - Host_UpdateBreakPointView(); -} - -void CBreakPoints::AddMemoryCheck(const TMemCheck& _rMemoryCheck) -{ - m_MemChecks.push_back(_rMemoryCheck); -} - -void CBreakPoints::AddAutoBreakpoints() -{ -#if defined(_DEBUG) || defined(DEBUGFAST) -#if 1 - const char *bps[] = { - "PPCHalt", - }; - - for (int i = 0; i < sizeof(bps) / sizeof(const char *); i++) - { - Symbol *symbol = g_symbolDB.GetSymbolFromName(bps[i]); - if (symbol) - AddBreakPoint(symbol->address, false); - } - Host_UpdateBreakPointView(); -#endif -#endif -} - -void CBreakPoints::DeleteElementByAddress(u32 _Address) -{ - // first check breakpoints - { - std::vector::iterator iter; - for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter) - { - if ((*iter).iAddress == _Address) - { - m_BreakPoints.erase(iter); - Host_UpdateBreakPointView(); - return; - } - } - } - - // second memory check checkpoint std::vector::iterator iter; for (iter = m_MemChecks.begin(); iter != m_MemChecks.end(); ++iter) { diff --git a/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.h b/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.h index 28248ab525..38ecd249ac 100644 --- a/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.h +++ b/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.h @@ -32,7 +32,9 @@ struct TBreakPoint struct TMemCheck { - TMemCheck(); + TMemCheck() { + numHits = 0; + } u32 StartAddress; u32 EndAddress; @@ -49,51 +51,51 @@ struct TMemCheck void Action(u32 _iValue, u32 addr, bool write, int size, u32 pc); }; -class CBreakPoints + +// Code breakpoints. +class BreakPoints { public: - typedef std::vector TBreakPoints; - typedef std::vector TMemChecks; static const TBreakPoints& GetBreakPoints() { return m_BreakPoints; } - static const TMemChecks& GetMemChecks() { return m_MemChecks; } // is address breakpoint static bool IsAddressBreakPoint(u32 _iAddress); - - //memory breakpoint - static TMemCheck *GetMemCheck(u32 address); - - // is break on count - static void SetBreakCount(u32 count) { m_iBreakOnCount = count; } - static u32 GetBreakCount() { return m_iBreakOnCount; } - static bool IsTempBreakPoint(u32 _iAddress); // AddBreakPoint - static void AddBreakPoint(u32 em_address, bool temp=false); + static void Add(u32 em_address, bool temp=false); // Remove Breakpoint - static void RemoveBreakPoint(u32 _iAddress); + static void Remove(u32 _iAddress); + static void Clear(); - static void AddMemoryCheck(const TMemCheck& _rMemoryCheck); - - static void ClearAllBreakPoints(); static void UpdateBreakPointView(); static void AddAutoBreakpoints(); - - static void DeleteElementByAddress(u32 _Address); + static void DeleteByAddress(u32 _Address); private: - static TBreakPoints m_BreakPoints; - - static TMemChecks m_MemChecks; - static u32 m_iBreakOnCount; +}; + +// Memory breakpoints +class MemChecks +{ +public: + typedef std::vector TMemChecks; + static TMemChecks m_MemChecks; + static const TMemChecks& GetMemChecks() { return m_MemChecks; } + static void Add(const TMemCheck& _rMemoryCheck); + + //memory breakpoint + static TMemCheck *GetMemCheck(u32 address); + static void DeleteByAddress(u32 _Address); + + void Clear(); }; #endif diff --git a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp index 7a88f3a4a4..c129fc9268 100644 --- a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp +++ b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp @@ -81,24 +81,27 @@ bool PPCDebugInterface::isAlive() bool PPCDebugInterface::isBreakpoint(unsigned int address) { - return CBreakPoints::IsAddressBreakPoint(address); + return BreakPoints::IsAddressBreakPoint(address); } void PPCDebugInterface::setBreakpoint(unsigned int address) { - CBreakPoints::AddBreakPoint(address); + BreakPoints::Add(address); } void PPCDebugInterface::clearBreakpoint(unsigned int address) { - CBreakPoints::RemoveBreakPoint(address); + BreakPoints::Remove(address); } void PPCDebugInterface::clearAllBreakpoints() {} void PPCDebugInterface::toggleBreakpoint(unsigned int address) { - CBreakPoints::IsAddressBreakPoint(address) ? CBreakPoints::RemoveBreakPoint(address) : CBreakPoints::AddBreakPoint(address); + if (BreakPoints::IsAddressBreakPoint(address)) + BreakPoints::Remove(address); + else + BreakPoints::Add(address); } void PPCDebugInterface::insertBLR(unsigned int address) diff --git a/Source/Core/Core/Src/HLE/HLE.cpp b/Source/Core/Core/Src/HLE/HLE.cpp index d5c277b0af..13d55f5a08 100644 --- a/Source/Core/Core/Src/HLE/HLE.cpp +++ b/Source/Core/Core/Src/HLE/HLE.cpp @@ -115,7 +115,7 @@ void PatchFunctions() Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName); if (symbol > 0) { - CBreakPoints::AddBreakPoint(symbol->address, false); + BreakPoints::Add(symbol->address, false); LOG(HLE,"Adding BP to %s %08x", OSBreakPoints[i].m_szPatchName, symbol->address); } } diff --git a/Source/Core/Core/Src/HW/CPU.cpp b/Source/Core/Core/Src/HW/CPU.cpp index 21896a76a2..a7f1ed6c55 100644 --- a/Source/Core/Core/Src/HW/CPU.cpp +++ b/Source/Core/Core/Src/HW/CPU.cpp @@ -69,19 +69,19 @@ void CCPU::Run() }*/ //2: check for breakpoint - if (CBreakPoints::IsAddressBreakPoint(PC)) + if (BreakPoints::IsAddressBreakPoint(PC)) { LOG(GEKKO, "Hit Breakpoint - %08x", PC); EnableStepping(true); - if (CBreakPoints::IsTempBreakPoint(PC)) - CBreakPoints::RemoveBreakPoint(PC); + if (BreakPoints::IsTempBreakPoint(PC)) + BreakPoints::Remove(PC); Host_UpdateDisasmDialog(); break; } -/* if (!Core::g_CoreStartupParameter.bUseJIT && CBreakPoints::GetBreakCount() == PowerPC::ppcState.DebugCount) +/* if (!Core::g_CoreStartupParameter.bUseJIT && BreakPoints::GetBreakCount() == PowerPC::ppcState.DebugCount) { LOG(GEKKO, "Hit DebugCount breakpoint - %i", PowerPC::ppcState.DebugCount); EnableStepping(true); @@ -183,19 +183,12 @@ void CCPU::SingleStep() } //2: check for breakpoint - if (CBreakPoints::IsAddressBreakPoint(PC)) + if (BreakPoints::IsAddressBreakPoint(PC)) { LOG(GEKKO, "Hit Breakpoint - %08x", PC); EnableStepping(true); - if (CBreakPoints::IsTempBreakPoint(PC)) - CBreakPoints::RemoveBreakPoint(PC); - break; - } - - if (!Core::g_CoreStartupParameter.bUseJIT && CBreakPoints::GetBreakCount() == PowerPC::ppcState.DebugCount) - { - LOG(GEKKO, "Hit DebugCount breakpoint - %i", PowerPC::ppcState.DebugCount); - EnableStepping(true); + if (BreakPoints::IsTempBreakPoint(PC)) + BreakPoints::Remove(PC); break; } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index fb874666e2..a8440d920b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -25,6 +25,7 @@ #include "../../Core.h" #include "../../PatchEngine.h" #include "../../CoreTiming.h" +#include "../../Debugger/Debugger_Breakpoints.h" #include "../PowerPC.h" #include "../Profiler.h" #include "../PPCTables.h" @@ -42,15 +43,14 @@ using namespace PowerPC; extern int blocksExecuted; // Dolphin's PowerPC->x86 JIT dynamic recompiler -// All code by ector (hrydgard) +// (Nearly) all code by ector (hrydgard) // Features: // * x86 & x64 support, lots of shared code. // * Basic block linking // * Fast dispatcher // Unfeatures: -// * Does not recompile all instructions. Often falls back to inserting a CALL to the corresponding JIT function. - +// * Does not recompile all instructions - sometimes falls back to inserting a CALL to the corresponding JIT function. // Various notes below @@ -74,22 +74,22 @@ extern int blocksExecuted; // This can even be seen in one homebrew Wii demo - RayTracer.elf // Other considerations - -//Many instructions have shorter forms for EAX. However, I believe their performance boost -//will be as small to be negligble, so I haven't dirtied up the code with that. AMD recommends it in their -//optimization manuals, though. - +// +// Many instructions have shorter forms for EAX. However, I believe their performance boost +// will be as small to be negligble, so I haven't dirtied up the code with that. AMD recommends it in their +// optimization manuals, though. +// // We support block linking. Reserve space at the exits of every block for a full 5-byte jmp. Save 16-bit offsets // from the starts of each block, marking the exits so that they can be nicely patched at any time. - -// * Blocks do NOT use call/ret, they only jmp to each other and to the dispatcher when necessary. - +// +// Blocks do NOT use call/ret, they only jmp to each other and to the dispatcher when necessary. +// // All blocks that can be precompiled will be precompiled. Code will be memory protected - any write will mark // the region as non-compilable, and all links to the page will be torn out and replaced with dispatcher jmps. - +// // Alternatively, icbi instruction SHOULD mark where we can't compile - -// Seldom-happening events will be handled by adding a decrement of a counter to all blr instructions (which are +// +// Seldom-happening events is handled by adding a decrement of a counter to all blr instructions (which are // expensive anyway since we need to return to dispatcher, except when they can be predicted). // TODO: SERIOUS synchronization problem with the video plugin setting tokens and breakpoints in dual core mode!!! @@ -113,10 +113,6 @@ extern int blocksExecuted; CR2-CR4 are non-volatile, rest of CR is volatile -> dropped on blr. R5-R12 are volatile -> dropped on blr. * classic inlining across calls. - -Metroid wants -subc -subfe Low hanging fruit: stfd -- guaranteed in memory @@ -381,7 +377,6 @@ namespace CPUCompare //Analyze the block, collect all instructions it is made of (including inlining, //if that is enabled), reorder instructions for optimal performance, and join joinable instructions. - PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, &code_buffer); PPCAnalyst::CodeOp *ops = code_buffer.codebuffer; diff --git a/Source/Core/DebuggerWX/Src/BreakPointDlg.cpp b/Source/Core/DebuggerWX/Src/BreakPointDlg.cpp index 318b8225ef..c1831ada07 100644 --- a/Source/Core/DebuggerWX/Src/BreakPointDlg.cpp +++ b/Source/Core/DebuggerWX/Src/BreakPointDlg.cpp @@ -17,6 +17,7 @@ #include "BreakPointDlg.h" #include "Common.h" +#include "Host.h" #include "Debugger.h" #include "StringUtil.h" #include "Debugger/Debugger_BreakPoints.h" @@ -76,8 +77,8 @@ void BreakPointDlg::OnOK(wxCommandEvent& /*event*/) u32 Address = 0; if (AsciiToHex(AddressString.mb_str(), Address)) { - CBreakPoints::AddBreakPoint(Address); - CBreakPoints::UpdateBreakPointView(); + BreakPoints::Add(Address); + Host_UpdateBreakPointView(); Close(); } } diff --git a/Source/Core/DebuggerWX/Src/BreakpointView.cpp b/Source/Core/DebuggerWX/Src/BreakpointView.cpp index c3da612491..075397c498 100644 --- a/Source/Core/DebuggerWX/Src/BreakpointView.cpp +++ b/Source/Core/DebuggerWX/Src/BreakpointView.cpp @@ -47,7 +47,7 @@ void CBreakPointView::Update() InsertColumn(4, wxT("Flags"), wxLIST_FORMAT_CENTER, 100); char szBuffer[64]; - const CBreakPoints::TBreakPoints& rBreakPoints = CBreakPoints::GetBreakPoints(); + const BreakPoints::TBreakPoints& rBreakPoints = BreakPoints::GetBreakPoints(); for (size_t i = 0; i < rBreakPoints.size(); i++) { const TBreakPoint& rBP = rBreakPoints[i]; @@ -74,7 +74,7 @@ void CBreakPointView::Update() } } - const CBreakPoints::TMemChecks& rMemChecks = CBreakPoints::GetMemChecks(); + const MemChecks::TMemChecks& rMemChecks = MemChecks::GetMemChecks(); for (size_t i = 0; i < rMemChecks.size(); i++) { const TMemCheck& rMemCheck = rMemChecks[i]; @@ -106,7 +106,6 @@ void CBreakPointView::Update() SetItemData(Item, rMemCheck.StartAddress); } - Refresh(); } @@ -116,6 +115,8 @@ void CBreakPointView::DeleteCurrentSelection() if (Item >= 0) { u32 Address = (u32)GetItemData(Item); - CBreakPoints::DeleteElementByAddress(Address); + BreakPoints::DeleteByAddress(Address); + MemChecks::DeleteByAddress(Address); + Update(); } } diff --git a/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp b/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp index bcd812ebfc..8dd3e45dc0 100644 --- a/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp +++ b/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp @@ -22,6 +22,7 @@ #include "HW/Memmap.h" #include "BreakPointDlg.h" #include "MemoryCheckDlg.h" +#include "Host.h" #include "IniFile.h" #include "Debugger/Debugger_BreakPoints.h" // for TMemCheck @@ -205,7 +206,7 @@ CBreakPointWindow::OnDelete(wxCommandEvent& event) void CBreakPointWindow::OnClear(wxCommandEvent& event) { - CBreakPoints::ClearAllBreakPoints(); + BreakPoints::Clear(); } // ============ @@ -244,11 +245,11 @@ CBreakPointWindow::OnAddBreakPointMany(wxCommandEvent& event) u32 Address = 0; if (AsciiToHex(line.c_str(), Address)) { - CBreakPoints::AddBreakPoint(Address); + BreakPoints::Add(Address); } } // only update after we are done with the loop - CBreakPoints::UpdateBreakPointView(); + Host_UpdateBreakPointView(); } else { @@ -338,7 +339,7 @@ CBreakPointWindow::OnAddMemoryCheckMany(wxCommandEvent& event) MemCheck.Break = true; } - if(doCommon) + if (doCommon) { // settings for the memory check MemCheck.OnRead = true; @@ -346,11 +347,11 @@ CBreakPointWindow::OnAddMemoryCheckMany(wxCommandEvent& event) MemCheck.Log = true; //MemCheck.Break = false; // this is also what sets Active "on" in the breakpoint window // so don't think it's off because we are only writing this to the log - CBreakPoints::AddMemoryCheck(MemCheck); + MemChecks::Add(MemCheck); } } // update after we are done with the loop - CBreakPoints::UpdateBreakPointView(); + Host_UpdateBreakPointView(); } else { diff --git a/Source/Core/DebuggerWX/Src/CodeView.cpp b/Source/Core/DebuggerWX/Src/CodeView.cpp index 813be810c0..d59b6b69a3 100644 --- a/Source/Core/DebuggerWX/Src/CodeView.cpp +++ b/Source/Core/DebuggerWX/Src/CodeView.cpp @@ -119,6 +119,7 @@ void CCodeView::OnMouseDown(wxMouseEvent& event) { debugger->toggleBreakpoint(YToAddress(y)); redraw(); + Host_UpdateBreakPointView(); } event.Skip(true); diff --git a/Source/Core/DebuggerWX/Src/MemoryCheckDlg.cpp b/Source/Core/DebuggerWX/Src/MemoryCheckDlg.cpp index 2adc1413c7..135d019703 100644 --- a/Source/Core/DebuggerWX/Src/MemoryCheckDlg.cpp +++ b/Source/Core/DebuggerWX/Src/MemoryCheckDlg.cpp @@ -19,6 +19,7 @@ #include "Common.h" #include "Debugger.h" #include "StringUtil.h" +#include "Host.h" #include "Debugger/Debugger_BreakPoints.h" BEGIN_EVENT_TABLE(MemoryCheckDlg,wxDialog) @@ -100,8 +101,8 @@ void MemoryCheckDlg::OnOK(wxCommandEvent& /*event*/) MemCheck.Log = true; MemCheck.Break = true; - CBreakPoints::AddMemoryCheck(MemCheck); - CBreakPoints::UpdateBreakPointView(); + MemChecks::Add(MemCheck); + Host_UpdateBreakPointView(); Close(); } }