[Debugger] Add GPR read/write breakpoints

This commit is contained in:
shygoo 2019-01-20 02:52:49 -06:00
parent 9a80a4970a
commit 7a1dd3835b
9 changed files with 471 additions and 189 deletions

View File

@ -17,7 +17,13 @@
#include <Project64-core/N64System/Mips/OpcodeName.h>
#include <Project64-core/N64System/N64Class.h>
CBreakpoints::CBreakpoints()
CBreakpoints::CBreakpoints() :
m_GPRWriteBP(0),
m_GPRReadBP(0),
m_HIWriteBP(false),
m_HIReadBP(false),
m_LOWriteBP(false),
m_LOReadBP(false)
{
}
@ -348,6 +354,23 @@ size_t CBreakpoints::NumMemLocks()
return m_MemLocks.size();
}
bool CBreakpoints::HaveAnyGPRWriteBP(void) { return m_GPRWriteBP != 0; }
bool CBreakpoints::HaveAnyGPRReadBP(void) { return m_GPRReadBP != 0; }
bool CBreakpoints::HaveGPRWriteBP(int nReg) { return (m_GPRWriteBP & (1 << nReg)) != 0; }
bool CBreakpoints::HaveGPRReadBP(int nReg) { return (m_GPRReadBP & (1 << nReg)) != 0; }
void CBreakpoints::ToggleGPRWriteBP(int nReg) { m_GPRWriteBP ^= (1 << nReg); }
void CBreakpoints::ToggleGPRReadBP(int nReg) { m_GPRReadBP ^= (1 << nReg); }
bool CBreakpoints::HaveHIWriteBP(void) { return m_HIWriteBP; }
bool CBreakpoints::HaveHIReadBP(void) { return m_HIReadBP; }
bool CBreakpoints::HaveLOWriteBP(void) { return m_LOWriteBP; }
bool CBreakpoints::HaveLOReadBP(void) { return m_LOReadBP; }
void CBreakpoints::ToggleHIWriteBP(void) { m_HIWriteBP = !m_HIWriteBP; }
void CBreakpoints::ToggleHIReadBP(void) { m_HIReadBP = !m_HIReadBP; }
void CBreakpoints::ToggleLOWriteBP(void) { m_LOWriteBP = !m_LOWriteBP; }
void CBreakpoints::ToggleLOReadBP(void) { m_LOReadBP = !m_LOReadBP; }
void CBreakpoints::PreUpdateBP()
{
if (g_BaseSystem)

View File

@ -67,6 +67,22 @@ public:
void ClearMemLocks(void);
size_t NumMemLocks(void);
bool HaveAnyGPRReadBP(void);
bool HaveAnyGPRWriteBP(void);
bool HaveGPRWriteBP(int nReg);
bool HaveGPRReadBP(int nReg);
void ToggleGPRWriteBP(int nReg);
void ToggleGPRReadBP(int nReg);
bool HaveHIWriteBP(void);
bool HaveHIReadBP(void);
bool HaveLOWriteBP(void);
bool HaveLOReadBP(void);
void ToggleHIWriteBP(void);
void ToggleHIReadBP(void);
void ToggleLOWriteBP(void);
void ToggleLOReadBP(void);
private:
void PreUpdateBP();
void PostUpdateBP();
@ -78,4 +94,7 @@ private:
breakpoints_t m_Execution;
memlocks_t m_MemLocks;
uint32_t m_GPRWriteBP, m_GPRReadBP;
bool m_HIWriteBP, m_HIReadBP, m_LOWriteBP, m_LOReadBP;
};

View File

@ -88,6 +88,8 @@ LRESULT CDebugCommandsView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARA
DlgSavePos_Init(DebuggerUI_CommandsPos);
DlgToolTip_Init();
m_RegisterTabs.SetDebugger(m_Debugger);
// Setup address input
m_AddressEdit.SetDisplayType(CEditNumber32::DisplayHex);
m_AddressEdit.SetLimitText(8);

View File

@ -15,6 +15,7 @@
#include "OpInfo.h"
bool CRegisterTabs::m_bColorsEnabled = false;
CDebuggerUI* CRegisterTabs::m_Debugger = NULL;
CRegisterTabs::CRegisterTabs() :
m_attached(false)
@ -279,7 +280,7 @@ void CRegisterTabs::RegisterChanged(HWND hDlg, TAB_ID srcTabId, WPARAM wParam)
return;
}
int ctrlId = LOWORD(wParam);
WORD ctrlId = LOWORD(wParam);
CWindow editCtrl = ::GetDlgItem(hDlg, ctrlId);
char text[20];
@ -298,7 +299,7 @@ void CRegisterTabs::RegisterChanged(HWND hDlg, TAB_ID srcTabId, WPARAM wParam)
}
else
{
int nReg = MapEditRegNum(ctrlId, GPREditIds, sizeof(GPREditIds) / sizeof(GPREditIds[0]));
int nReg = GetCtrlRegNum(ctrlId, GPREditIds);
g_Reg->m_GPR[nReg].UDW = value;
}
return;
@ -316,7 +317,7 @@ void CRegisterTabs::RegisterChanged(HWND hDlg, TAB_ID srcTabId, WPARAM wParam)
return;
}
int nReg = MapEditRegNum(ctrlId, FPREditIds, sizeof(FPREditIds) / sizeof(FPREditIds[0]));
int nReg = GetCtrlRegNum(ctrlId, FPREditIds);
*(uint32_t*)g_Reg->m_FPR_S[nReg] = value;
return;
}
@ -477,6 +478,7 @@ INT_PTR CALLBACK CRegisterTabs::TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, L
return TRUE;
}
// color textboxes
if (msg == WM_CTLCOLOREDIT)
{
HDC hdc = (HDC)wParam;
@ -484,7 +486,7 @@ INT_PTR CALLBACK CRegisterTabs::TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, L
COLORREF colorRead = RGB(200, 200, 255);
COLORREF colorWrite = RGB(255, 200, 200);
COLORREF colorBoth = RGB(255, 200, 255);
COLORREF colorBoth = RGB(220, 170, 255);
if (!m_bColorsEnabled || g_Reg == NULL || g_MMU == NULL)
{
@ -492,7 +494,7 @@ INT_PTR CALLBACK CRegisterTabs::TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, L
}
HWND hWnd = (HWND)lParam;
int ctrlId = ::GetWindowLong(hWnd, GWL_ID);
WORD ctrlId = (WORD) ::GetWindowLong(hWnd, GWL_ID);
COpInfo opInfo;
g_MMU->LW_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex);
@ -512,9 +514,20 @@ INT_PTR CALLBACK CRegisterTabs::TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, L
}
else
{
int nReg = MapEditRegNum(ctrlId, GPREditIds, sizeof(GPREditIds) / sizeof(GPREditIds[0]));
bOpReads = opInfo.ReadsGPR(nReg);
bOpWrites = opInfo.WritesGPR(nReg);
int nReg = GetCtrlRegNum(ctrlId, GPREditIds);
if (nReg == -1)
{
return (LRESULT)GetStockObject(DC_BRUSH);
}
int nRegRead1, nRegRead2, nRegWrite;
opInfo.ReadsGPR(&nRegRead1, &nRegRead2);
opInfo.WritesGPR(&nRegWrite);
bOpReads = (nReg == nRegRead1) || (nReg == nRegRead2);
bOpWrites = (nReg == nRegWrite);
}
if (bOpReads && bOpWrites)
@ -542,7 +555,134 @@ INT_PTR CALLBACK CRegisterTabs::TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, L
{
RegisterChanged(hDlg, TabGPR, wParam);
}
return FALSE;
}
// right click labels
if (msg == WM_CONTEXTMENU)
{
HWND hWnd = (HWND)wParam;
WORD ctrlId = (WORD) ::GetWindowLong(hWnd, GWL_ID);
CBreakpoints* breakpoints = m_Debugger->Breakpoints();
if (ctrlId == IDC_HI_LBL)
{
breakpoints->ToggleHIWriteBP();
}
else if (ctrlId == IDC_LO_LBL)
{
breakpoints->ToggleLOWriteBP();
}
else
{
int nReg = GetCtrlRegNum(ctrlId, GPRLabelIds);
if (nReg <= 0) // ignore R0
{
return FALSE;
}
breakpoints->ToggleGPRWriteBP(nReg);
}
::InvalidateRect(hWnd, NULL, true);
return FALSE;
}
// click labels
if (msg == WM_COMMAND && HIWORD(wParam) == STN_CLICKED || HIWORD(wParam) == STN_DBLCLK)
{
HWND hWnd = (HWND)lParam;
WORD ctrlId = LOWORD(wParam);
CBreakpoints* breakpoints = m_Debugger->Breakpoints();
if (ctrlId == IDC_HI_LBL)
{
breakpoints->ToggleHIReadBP();
}
else if (ctrlId == IDC_LO_LBL)
{
breakpoints->ToggleLOReadBP();
}
else
{
int nReg = GetCtrlRegNum(ctrlId, GPRLabelIds);
if (nReg <= 0) // ignore R0
{
return FALSE;
}
breakpoints->ToggleGPRReadBP(nReg);
}
::InvalidateRect(hWnd, NULL, true);
return FALSE;
}
// color labels
if (msg == WM_CTLCOLORSTATIC)
{
HWND hWnd = (HWND)lParam;
WORD ctrlId = (WORD) ::GetWindowLong(hWnd, GWL_ID);
HDC hdc = (HDC)wParam;
COLORREF colorRead = RGB(200, 200, 255);
COLORREF colorWrite = RGB(255, 200, 200);
COLORREF colorBoth = RGB(220, 170, 255);
CBreakpoints* breakpoints = m_Debugger->Breakpoints();
bool haveRead, haveWrite;
if (ctrlId == IDC_HI_LBL)
{
haveRead = breakpoints->HaveHIReadBP();
haveWrite = breakpoints->HaveHIWriteBP();
}
else if (ctrlId == IDC_LO_LBL)
{
haveRead = breakpoints->HaveLOReadBP();
haveWrite = breakpoints->HaveLOWriteBP();
}
else
{
int nReg = GetCtrlRegNum(ctrlId, GPRLabelIds);
if (nReg == -1)
{
return FALSE;
}
haveRead = breakpoints->HaveGPRReadBP(nReg);
haveWrite = breakpoints->HaveGPRWriteBP(nReg);
}
if (haveRead && haveWrite)
{
SetBkColor(hdc, colorBoth);
}
else if(haveRead)
{
SetBkColor(hdc, colorRead);
}
else if(haveWrite)
{
SetBkColor(hdc, colorWrite);
}
else
{
return FALSE;
}
return (LRESULT)GetStockObject(DC_BRUSH);
}
return FALSE;
}
@ -632,6 +772,11 @@ void CRegisterTabs::SetColorsEnabled(bool bColorsEnabled)
m_bColorsEnabled = bColorsEnabled;
}
void CRegisterTabs::SetDebugger(CDebuggerUI* debugger)
{
m_Debugger = debugger;
}
void CRegisterTabs::InitRegisterEdit(CWindow& tab, CEditNumber32& edit, WORD ctrlId)
{
edit.Attach(tab.GetDlgItem(ctrlId));

View File

@ -54,6 +54,7 @@ public:
void RedrawCurrentTab();
void RefreshEdits();
void SetColorsEnabled(bool bColorsEnabled);
void SetDebugger(CDebuggerUI* debugger);
private:
CRegisterTabs(const CRegisterTabs&); // Disable copy constructor
@ -91,6 +92,19 @@ private:
};
} CAUSE;
static constexpr WORD GPRLabelIds[] =
{
IDC_R0_LBL, IDC_R1_LBL, IDC_R2_LBL, IDC_R3_LBL,
IDC_R4_LBL, IDC_R5_LBL, IDC_R6_LBL, IDC_R7_LBL,
IDC_R8_LBL, IDC_R9_LBL, IDC_R10_LBL, IDC_R11_LBL,
IDC_R12_LBL, IDC_R13_LBL, IDC_R14_LBL, IDC_R15_LBL,
IDC_R16_LBL, IDC_R17_LBL, IDC_R18_LBL, IDC_R19_LBL,
IDC_R20_LBL, IDC_R21_LBL, IDC_R22_LBL, IDC_R23_LBL,
IDC_R24_LBL, IDC_R25_LBL, IDC_R26_LBL, IDC_R27_LBL,
IDC_R28_LBL, IDC_R29_LBL, IDC_R30_LBL, IDC_R31_LBL,
NULL
};
static constexpr WORD GPREditIds[] =
{
IDC_R0_EDIT, IDC_R1_EDIT, IDC_R2_EDIT, IDC_R3_EDIT,
@ -101,6 +115,7 @@ private:
IDC_R20_EDIT, IDC_R21_EDIT, IDC_R22_EDIT, IDC_R23_EDIT,
IDC_R24_EDIT, IDC_R25_EDIT, IDC_R26_EDIT, IDC_R27_EDIT,
IDC_R28_EDIT, IDC_R29_EDIT, IDC_R30_EDIT, IDC_R31_EDIT,
NULL
};
static constexpr WORD FPREditIds[] =
@ -113,6 +128,7 @@ private:
IDC_F20_EDIT, IDC_F21_EDIT, IDC_F22_EDIT, IDC_F23_EDIT,
IDC_F24_EDIT, IDC_F25_EDIT, IDC_F26_EDIT, IDC_F27_EDIT,
IDC_F28_EDIT, IDC_F29_EDIT, IDC_F30_EDIT, IDC_F31_EDIT,
NULL
};
static constexpr WORD COP0EditIds[] =
@ -122,6 +138,7 @@ private:
IDC_COP0_8_EDIT, IDC_COP0_9_EDIT, IDC_COP0_10_EDIT, IDC_COP0_11_EDIT,
IDC_COP0_12_EDIT, IDC_COP0_13_EDIT, IDC_COP0_14_EDIT, IDC_COP0_15_EDIT,
IDC_COP0_16_EDIT, IDC_COP0_17_EDIT, IDC_COP0_18_EDIT,
NULL
};
static constexpr WORD RDRAMEditIds[] =
@ -129,23 +146,27 @@ private:
IDC_RDRAM00_EDIT, IDC_RDRAM04_EDIT, IDC_RDRAM08_EDIT, IDC_RDRAM0C_EDIT,
IDC_RDRAM10_EDIT, IDC_RDRAM14_EDIT, IDC_RDRAM18_EDIT, IDC_RDRAM1C_EDIT,
IDC_RDRAM20_EDIT, IDC_RDRAM24_EDIT,
NULL
};
static constexpr WORD SPEditIds[] =
{
IDC_SP00_EDIT, IDC_SP04_EDIT, IDC_SP08_EDIT, IDC_SP0C_EDIT,
IDC_SP10_EDIT, IDC_SP14_EDIT, IDC_SP18_EDIT, IDC_SP1C_EDIT,
NULL
};
static constexpr WORD DPCEditIds[] =
{
IDC_DPC00_EDIT, IDC_DPC04_EDIT, IDC_DPC08_EDIT, IDC_DPC0C_EDIT,
IDC_DPC10_EDIT, IDC_DPC14_EDIT, IDC_DPC18_EDIT, IDC_DPC1C_EDIT,
NULL
};
static constexpr WORD MIEditIds[] =
{
IDC_MI00_EDIT, IDC_MI04_EDIT, IDC_MI08_EDIT, IDC_MI0C_EDIT,
NULL
};
static constexpr WORD VIEditIds[] =
@ -154,12 +175,14 @@ private:
IDC_VI10_EDIT, IDC_VI14_EDIT, IDC_VI18_EDIT, IDC_VI1C_EDIT,
IDC_VI20_EDIT, IDC_VI24_EDIT, IDC_VI28_EDIT, IDC_VI2C_EDIT,
IDC_VI30_EDIT, IDC_VI34_EDIT,
NULL
};
static constexpr WORD AIEditIds[] =
{
IDC_AI00_EDIT, IDC_AI04_EDIT, IDC_AI08_EDIT, IDC_AI0C_EDIT,
IDC_AI10_EDIT, IDC_AI14_EDIT,
NULL
};
static constexpr WORD PIEditIds[] =
@ -168,17 +191,20 @@ private:
IDC_PI10_EDIT, IDC_PI14_EDIT, IDC_PI18_EDIT, IDC_PI1C_EDIT,
IDC_PI20_EDIT, IDC_PI24_EDIT, IDC_PI28_EDIT, IDC_PI2C_EDIT,
IDC_PI30_EDIT,
NULL
};
static constexpr WORD RIEditIds[] =
{
IDC_RI00_EDIT, IDC_RI04_EDIT, IDC_RI08_EDIT, IDC_RI0C_EDIT,
IDC_RI10_EDIT, IDC_RI14_EDIT, IDC_RI18_EDIT, IDC_RI1C_EDIT,
NULL
};
static constexpr WORD SIEditIds[] =
{
IDC_SI00_EDIT, IDC_SI04_EDIT, IDC_SI08_EDIT, IDC_SI0C_EDIT,
NULL
};
static constexpr WORD DDEditIds[] =
@ -188,13 +214,15 @@ private:
IDC_DD20_EDIT, IDC_DD24_EDIT, IDC_DD28_EDIT, IDC_DD2C_EDIT,
IDC_DD30_EDIT, IDC_DD34_EDIT, IDC_DD38_EDIT, IDC_DD3C_EDIT,
IDC_DD40_EDIT, IDC_DD44_EDIT, IDC_DD48_EDIT,
NULL
};
static int MapEditRegNum(DWORD controlId, const WORD* edits, uint32_t ctrlIdsCount)
// return reg num associated with the control or -1 if ctrl isn't in map
static int GetCtrlRegNum(WORD ctrlId, const WORD* map)
{
for (uint32_t i = 0, n = ctrlIdsCount; i < n; i++)
for (uint32_t i = 0; map[i] != NULL; i++)
{
if (edits[i] == controlId)
if (map[i] == ctrlId)
{
return i;
}
@ -240,6 +268,7 @@ private:
// for static dlgprocs, assumes single instance
static bool m_bColorsEnabled;
static CDebuggerUI* m_Debugger;
vector<CWindow> m_TabWindows;
bool m_attached;

View File

@ -717,6 +717,37 @@ void CDebuggerUI::CPUStepStarted()
HandleCPUException();
}
}
if (m_Breakpoints->HaveAnyGPRWriteBP())
{
int nReg = 0;
opInfo.WritesGPR(&nReg);
if (nReg != 0 && m_Breakpoints->HaveGPRWriteBP(nReg))
{
g_Settings->SaveBool(Debugger_SteppingOps, true);
}
}
if (m_Breakpoints->HaveAnyGPRReadBP())
{
int nReg1 = 0, nReg2 = 0;
opInfo.ReadsGPR(&nReg1, &nReg2);
if ((nReg1 != 0 && m_Breakpoints->HaveGPRReadBP(nReg1)) ||
(nReg2 != 0 && m_Breakpoints->HaveGPRReadBP(nReg2)))
{
g_Settings->SaveBool(Debugger_SteppingOps, true);
}
}
if (m_Breakpoints->HaveHIWriteBP() && opInfo.WritesHI() ||
m_Breakpoints->HaveLOWriteBP() && opInfo.WritesLO() ||
m_Breakpoints->HaveHIReadBP() && opInfo.ReadsHI() ||
m_Breakpoints->HaveLOReadBP() && opInfo.ReadsLO())
{
g_Settings->SaveBool(Debugger_SteppingOps, true);
}
}
// Called before opcode is executed (not called if SkipOp is set)

View File

@ -156,12 +156,14 @@ public:
m_OpCode.op >= R4300i_SC && m_OpCode.op <= R4300i_SD);
}
// addiu sp, sp, x
bool IsStackShift()
{
return (m_OpCode.op == R4300i_ADDIU || m_OpCode.op == R4300i_ADDI) && m_OpCode.rt == 29;
}
bool IsStackAlloc()
// addiu sp, sp, <negative value>
bool IsStackAlloc()
{
if (!IsStackShift())
{
@ -171,7 +173,8 @@ public:
return (short)m_OpCode.immediate < 0;
}
bool IsStackFree()
// addiu sp, sp, <positive value>
bool IsStackFree()
{
if (!IsStackShift())
{
@ -181,7 +184,7 @@ public:
return (short)m_OpCode.immediate > 0;
}
bool ReadsGPR(unsigned int nReg)
void ReadsGPR(int* nReg1, int* nReg2)
{
uint32_t op = m_OpCode.op;
@ -189,165 +192,156 @@ public:
{
uint32_t fn = m_OpCode.funct;
if (m_OpCode.rs == nReg || m_OpCode.rt == nReg)
if (fn >= R4300i_SPECIAL_SLLV && fn <= R4300i_SPECIAL_SRAV ||
fn >= R4300i_SPECIAL_DSLLV && fn <= R4300i_SPECIAL_DSRAV ||
fn >= R4300i_SPECIAL_MULT && fn <= R4300i_SPECIAL_TNE)
{
if (fn >= R4300i_SPECIAL_SLLV && fn <= R4300i_SPECIAL_SRAV ||
fn >= R4300i_SPECIAL_DSLLV && fn <= R4300i_SPECIAL_DSRAV ||
fn >= R4300i_SPECIAL_MULT && fn <= R4300i_SPECIAL_TNE)
{
return true;
}
if (m_OpCode.rs == nReg)
{
if (fn == R4300i_SPECIAL_MTLO || fn == R4300i_SPECIAL_MTHI ||
fn == R4300i_SPECIAL_JR || fn == R4300i_SPECIAL_JALR)
{
return true;
}
}
if (m_OpCode.rt == nReg)
{
if (fn >= R4300i_SPECIAL_SLL && fn <= R4300i_SPECIAL_SRA ||
fn >= R4300i_SPECIAL_DSLL && fn <= R4300i_SPECIAL_DSRA32)
{
return true;
}
}
*nReg1 = m_OpCode.rs;
*nReg2 = m_OpCode.rt;
return;
}
if (fn == R4300i_SPECIAL_MTLO || fn == R4300i_SPECIAL_MTHI ||
fn == R4300i_SPECIAL_JR || fn == R4300i_SPECIAL_JALR)
{
*nReg1 = m_OpCode.rs;
*nReg2 = 0;
return;
}
if (fn >= R4300i_SPECIAL_SLL && fn <= R4300i_SPECIAL_SRA ||
fn >= R4300i_SPECIAL_DSLL && fn <= R4300i_SPECIAL_DSRA32)
{
*nReg1 = m_OpCode.rt;
*nReg2 = 0;
return;
}
*nReg1 = 0;
*nReg2 = 0;
return;
}
else
if (op >= R4300i_SB && op <= R4300i_SWR ||
op == R4300i_SC || op == R4300i_SD ||
op == R4300i_BEQ || op == R4300i_BEQL ||
op == R4300i_BNE || op == R4300i_BNEL)
{
if (m_OpCode.rs == nReg || m_OpCode.rt == nReg)
*nReg1 = m_OpCode.rs;
*nReg2 = m_OpCode.rt;
return;
}
if (op >= R4300i_BLEZL && op <= R4300i_LWU ||
op >= R4300i_BLEZ && op <= R4300i_XORI ||
op >= R4300i_CACHE && op <= R4300i_LD ||
op >= R4300i_SWC1 && op <= R4300i_SDC2 ||
op == R4300i_REGIMM)
{
*nReg1 = m_OpCode.rs;
*nReg2 = 0;
return;
}
if (op == R4300i_CP0 && m_OpCode.fmt == R4300i_COP0_MT)
{
*nReg1 = m_OpCode.rt;
*nReg2 = 0;
return;
}
if (op == R4300i_CP1)
{
if (m_OpCode.fmt == R4300i_COP1_MT ||
m_OpCode.fmt == R4300i_COP1_DMT ||
m_OpCode.fmt == R4300i_COP1_CT)
{
if (op >= R4300i_SB && op <= R4300i_SWR ||
op >= R4300i_SC && op <= R4300i_SD ||
op == R4300i_BEQ || op == R4300i_BEQL ||
op == R4300i_BNE || op == R4300i_BNEL)
{
return true;
}
if (m_OpCode.rs == nReg)
{
if (op == R4300i_REGIMM)
{
return true;
}
if (op >= R4300i_BLEZL && op <= R4300i_LWU ||
op >= R4300i_BLEZ && op <= R4300i_XORI ||
op >= R4300i_CACHE && op <= R4300i_LD ||
op == R4300i_SWC1 || op == R4300i_SDC1)
{
return true;
}
}
if (m_OpCode.rt == nReg)
{
if (op == R4300i_CP0 && m_OpCode.fmt == R4300i_COP0_MT)
{
return true;
}
if (op == R4300i_CP1)
{
if (m_OpCode.fmt == R4300i_COP1_MT ||
m_OpCode.fmt == R4300i_COP1_DMT ||
m_OpCode.fmt == R4300i_COP1_CT)
{
return true;
}
}
}
*nReg1 = m_OpCode.rt;
*nReg2 = 0;
return;
}
}
return false;
*nReg1 = 0;
*nReg2 = 0;
}
bool WritesGPR(unsigned int nReg)
inline void WritesGPR(int* nReg)
{
uint32_t op = m_OpCode.op;
if (op == R4300i_SPECIAL)
{
if (m_OpCode.rd == nReg)
{
uint32_t fn = m_OpCode.funct;
uint32_t fn = m_OpCode.funct;
if (fn >= R4300i_SPECIAL_SLL && fn <= R4300i_SPECIAL_SRAV ||
fn >= R4300i_SPECIAL_DSLLV && fn <= R4300i_SPECIAL_DSRAV ||
fn >= R4300i_SPECIAL_DIVU && fn <= R4300i_SPECIAL_DSUBU ||
fn >= R4300i_SPECIAL_DSLL && fn <= R4300i_SPECIAL_DSRA32 ||
fn == R4300i_SPECIAL_JALR || fn == R4300i_SPECIAL_MFLO ||
fn == R4300i_SPECIAL_MFHI)
{
return true;
}
if (fn >= R4300i_SPECIAL_SLL && fn <= R4300i_SPECIAL_SRAV ||
fn >= R4300i_SPECIAL_DSLLV && fn <= R4300i_SPECIAL_DSRAV ||
fn >= R4300i_SPECIAL_DIVU && fn <= R4300i_SPECIAL_DSUBU ||
fn >= R4300i_SPECIAL_DSLL && fn <= R4300i_SPECIAL_DSRA32 ||
fn == R4300i_SPECIAL_JALR || fn == R4300i_SPECIAL_MFLO ||
fn == R4300i_SPECIAL_MFHI)
{
*nReg = m_OpCode.rd;
return;
}
*nReg = 0;
return;
}
if (op >= R4300i_DADDI && op <= R4300i_LWU ||
op >= R4300i_ADDI && op <= R4300i_LUI ||
op == R4300i_LL || op == R4300i_LD ||
(op == R4300i_CP0 && m_OpCode.fmt == R4300i_COP0_MF) ||
(op == R4300i_CP1 && m_OpCode.fmt == R4300i_COP1_MF) ||
(op == R4300i_CP1 && m_OpCode.fmt == R4300i_COP1_CF))
{
*nReg = m_OpCode.rt;
return;
}
if (op == R4300i_JAL)
{
*nReg = 31; // RA
return;
}
*nReg = 0;
}
inline bool ReadsHI()
{
return (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MFHI);
}
inline bool ReadsLO()
{
return (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MFLO);
}
inline bool WritesHI()
{
if (m_OpCode.op == R4300i_SPECIAL)
{
if (m_OpCode.funct == R4300i_SPECIAL_MTHI ||
m_OpCode.funct >= R4300i_SPECIAL_MULT && m_OpCode.funct <= R4300i_SPECIAL_DDIVU)
{
return true;
}
}
else
return false;
}
inline bool WritesLO()
{
if (m_OpCode.op == R4300i_SPECIAL)
{
if (m_OpCode.rt == nReg)
if (m_OpCode.funct == R4300i_SPECIAL_MTLO ||
m_OpCode.funct >= R4300i_SPECIAL_MULT && m_OpCode.funct <= R4300i_SPECIAL_DDIVU)
{
if (op >= R4300i_DADDI && op <= R4300i_LWU ||
op >= R4300i_ADDI && op <= R4300i_LUI ||
op == R4300i_LL || op == R4300i_LD ||
(op == R4300i_CP0 && m_OpCode.fmt == R4300i_COP0_MF) ||
(op == R4300i_CP1 && m_OpCode.fmt == R4300i_COP1_MF) ||
(op == R4300i_CP1 && m_OpCode.fmt == R4300i_COP1_CF))
{
return true;
}
return true;
}
}
if (op == R4300i_JAL && nReg == 31) // nReg == RA
{
return true;
}
return false;
}
bool ReadsLO()
{
if (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MFLO)
{
return true;
}
return false;
}
bool WritesLO()
{
if (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MTLO)
{
return true;
}
return false;
}
// todo add mult, div etc
bool ReadsHI()
{
if (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MFHI)
{
return true;
}
return false;
}
bool WritesHI()
{
if (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MTHI)
{
return true;
}
return false;
}

View File

@ -705,38 +705,38 @@ IDD_Debugger_RegGPR DIALOGEX 0, 0, 190, 210
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "R0",IDC_STATIC,3,15,10,8
LTEXT "AT",IDC_STATIC,3,26,10,8
LTEXT "V0",IDC_STATIC,3,37,10,8
LTEXT "V1",IDC_STATIC,3,48,10,8
LTEXT "A0",IDC_STATIC,3,59,10,8
LTEXT "A1",IDC_STATIC,3,70,10,8
LTEXT "A2",IDC_STATIC,3,81,10,8
LTEXT "A3",IDC_STATIC,3,92,10,8
LTEXT "T0",IDC_STATIC,3,103,10,8
LTEXT "T1",IDC_STATIC,3,114,10,8
LTEXT "T2",IDC_STATIC,3,125,10,8
LTEXT "T3",IDC_STATIC,3,136,10,8
LTEXT "T4",IDC_STATIC,3,147,10,8
LTEXT "T5",IDC_STATIC,3,158,10,8
LTEXT "T6",IDC_STATIC,3,169,10,8
LTEXT "T7",IDC_STATIC,3,180,10,8
LTEXT "S0",IDC_STATIC,95,15,10,8
LTEXT "S1",IDC_STATIC,95,26,10,8
LTEXT "S2",IDC_STATIC,95,37,10,8
LTEXT "S3",IDC_STATIC,95,48,10,8
LTEXT "S4",IDC_STATIC,95,59,10,8
LTEXT "S5",IDC_STATIC,95,70,10,8
LTEXT "S6",IDC_STATIC,95,81,10,8
LTEXT "S7",IDC_STATIC,95,92,10,8
LTEXT "T8",IDC_STATIC,95,103,10,8
LTEXT "T9",IDC_STATIC,95,114,10,8
LTEXT "K0",IDC_STATIC,95,125,10,8
LTEXT "K1",IDC_STATIC,95,136,10,8
LTEXT "GP",IDC_STATIC,95,147,10,8
LTEXT "SP",IDC_STATIC,95,158,10,8
LTEXT "FP",IDC_STATIC,95,169,10,8
LTEXT "RA",IDC_STATIC,95,180,10,8
LTEXT "R0",IDC_R0_LBL,3,15,10,8,SS_NOTIFY
LTEXT "AT",IDC_R1_LBL,3,26,10,8,SS_NOTIFY
LTEXT "V0",IDC_R2_LBL,3,37,10,8,SS_NOTIFY
LTEXT "V1",IDC_R3_LBL,3,48,10,8,SS_NOTIFY
LTEXT "A0",IDC_R4_LBL,3,59,10,8,SS_NOTIFY
LTEXT "A1",IDC_R5_LBL,3,70,10,8,SS_NOTIFY
LTEXT "A2",IDC_R6_LBL,3,81,10,8,SS_NOTIFY
LTEXT "A3",IDC_R7_LBL,3,92,10,8,SS_NOTIFY
LTEXT "T0",IDC_R8_LBL,3,103,10,8,SS_NOTIFY
LTEXT "T1",IDC_R9_LBL,3,114,10,8,SS_NOTIFY
LTEXT "T2",IDC_R10_LBL,3,125,10,8,SS_NOTIFY
LTEXT "T3",IDC_R11_LBL,3,136,10,8,SS_NOTIFY
LTEXT "T4",IDC_R12_LBL,3,147,10,8,SS_NOTIFY
LTEXT "T5",IDC_R13_LBL,3,158,10,8,SS_NOTIFY
LTEXT "T6",IDC_R14_LBL,3,169,10,8,SS_NOTIFY
LTEXT "T7",IDC_R15_LBL,3,180,10,8,SS_NOTIFY
LTEXT "S0",IDC_R16_LBL,95,15,10,8,SS_NOTIFY
LTEXT "S1",IDC_R17_LBL,95,26,10,8,SS_NOTIFY
LTEXT "S2",IDC_R18_LBL,95,37,10,8,SS_NOTIFY
LTEXT "S3",IDC_R19_LBL,95,48,10,8,SS_NOTIFY
LTEXT "S4",IDC_R20_LBL,95,59,10,8,SS_NOTIFY
LTEXT "S5",IDC_R21_LBL,95,70,10,8,SS_NOTIFY
LTEXT "S6",IDC_R22_LBL,95,81,10,8,SS_NOTIFY
LTEXT "S7",IDC_R23_LBL,95,92,10,8,SS_NOTIFY
LTEXT "T8",IDC_R24_LBL,95,103,10,8,SS_NOTIFY
LTEXT "T9",IDC_R25_LBL,95,114,10,8,SS_NOTIFY
LTEXT "K0",IDC_R26_LBL,95,125,10,8,SS_NOTIFY
LTEXT "K1",IDC_R27_LBL,95,136,10,8,SS_NOTIFY
LTEXT "GP",IDC_R28_LBL,95,147,10,8,SS_NOTIFY
LTEXT "SP",IDC_R29_LBL,95,158,10,8,SS_NOTIFY
LTEXT "FP",IDC_R30_LBL,95,169,10,8,SS_NOTIFY
LTEXT "RA",IDC_R31_LBL,95,180,10,8,SS_NOTIFY
EDITTEXT IDC_R0_EDIT,17,15,75,10,ES_UPPERCASE | ES_AUTOHSCROLL | WS_DISABLED,WS_EX_RIGHT
EDITTEXT IDC_R1_EDIT,17,26,75,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
EDITTEXT IDC_R2_EDIT,17,37,75,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
@ -769,12 +769,12 @@ BEGIN
EDITTEXT IDC_R29_EDIT,109,158,75,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
EDITTEXT IDC_R30_EDIT,109,169,75,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
EDITTEXT IDC_R31_EDIT,109,180,75,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
LTEXT "HI",IDC_STATIC,3,195,8,8
LTEXT "LO",IDC_STATIC,95,195,10,8
LTEXT "HI",IDC_HI_LBL,3,195,10,8,SS_NOTIFY
LTEXT "LO",IDC_LO_LBL,95,195,10,8,SS_NOTIFY
EDITTEXT IDC_HI_EDIT,17,195,75,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
EDITTEXT IDC_LO_EDIT,109,195,75,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
CONTROL "",IDC_STATIC,"Static",SS_GRAYFRAME | SS_SUNKEN,3,192,180,1
LTEXT "CPU General Purpose Registers",IDC_STATIC,3,4,100,8
LTEXT "CPU General Purpose Registers",IDC_STATIC,3,4,104,8
END
IDD_Debugger_AddBreakpoint DIALOGEX 0, 0, 107, 62
@ -2063,6 +2063,11 @@ BEGIN
0
END
IDD_Debugger_RegGPR AFX_DIALOG_LAYOUT
BEGIN
0
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog Info

View File

@ -641,6 +641,40 @@
#define IDC_CHK_FPE 1477
#define IDC_CHK_WATCH 1478
#define IDC_CHK_VCED 1479
#define IDC_R0_LBL 1481
#define IDC_R1_LBL 1482
#define IDC_R2_LBL 1483
#define IDC_R3_LBL 1484
#define IDC_R4_LBL 1485
#define IDC_R5_LBL 1486
#define IDC_R6_LBL 1487
#define IDC_R7_LBL 1488
#define IDC_R8_LBL 1489
#define IDC_R9_LBL 1490
#define IDC_R10_LBL 1491
#define IDC_R11_LBL 1492
#define IDC_R12_LBL 1493
#define IDC_R13_LBL 1494
#define IDC_R15_LBL 1495
#define IDC_R16_LBL 1496
#define IDC_R17_LBL 1497
#define IDC_R18_LBL 1498
#define IDC_R19_LBL 1499
#define IDC_R20_LBL 1500
#define IDC_R21_LBL 1501
#define IDC_R22_LBL 1502
#define IDC_R23_LBL 1503
#define IDC_R24_LBL 1504
#define IDC_R25_LBL 1505
#define IDC_R26_LBL 1506
#define IDC_R27_LBL 1507
#define IDC_R28_LBL 1508
#define IDC_R29_LBL 1509
#define IDC_R30_LBL 1510
#define IDC_R31_LBL 1511
#define IDC_R14_LBL 1512
#define IDC_HI_LBL 1513
#define IDC_LO_LBL 1514
#define ID_POPUP_SHOWINMEMORYVIEWER 40005
#define ID_POPUPMENU_PLAYGAMEWITHDISK 40008
#define ID_POPUPMENU_ADDSYMBOL 40013
@ -678,9 +712,9 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 209
#define _APS_NEXT_RESOURCE_VALUE 210
#define _APS_NEXT_COMMAND_VALUE 40043
#define _APS_NEXT_CONTROL_VALUE 1480
#define _APS_NEXT_CONTROL_VALUE 1515
#define _APS_NEXT_SYMED_VALUE 102
#endif
#endif