Skip to content

Commit

Permalink
Add formatting options for viewing registers
Browse files Browse the repository at this point in the history
All formatting are individual per registers and they all have one option to go back to their original hexadecimal form.

- GPR: signed integer, unsigned integer, float
- FPR: double

Also happened to come accross an issue where editing the PFR would ignore the higher 32 bits of the new value, this had to be fixed for the format to work.
  • Loading branch information
aldelaro5 authored and aldelaro5 committed Sep 8, 2016
1 parent f1964f9 commit ea2effc
Show file tree
Hide file tree
Showing 2 changed files with 258 additions and 42 deletions.
273 changes: 241 additions & 32 deletions Source/Core/DolphinWX/Debugger/RegisterView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,177 @@ enum
{
IDM_WATCHADDRESS,
IDM_VIEWMEMORY,
IDM_VIEWCODE
IDM_VIEWCODE,
IDM_VIEW_HEX8,
IDM_VIEW_HEX16,
IDM_VIEW_FLOAT,
IDM_VIEW_DOUBLE,
IDM_VIEW_UINT,
IDM_VIEW_INT
};

static const char* special_reg_names[] = {"PC", "LR", "CTR", "CR", "FPSCR",
"MSR", "SRR0", "SRR1", "Exceptions", "Int Mask",
"Int Cause", "DSISR", "DAR", "PT hashmask"};
enum class FormatSpecifier
{
Hex8,
Hex16,
Float,
Double,
UInt,
Int
};

constexpr const char* special_reg_names[] = {"PC", "LR", "CTR", "CR", "FPSCR",
"MSR", "SRR0", "SRR1", "Exceptions", "Int Mask",
"Int Cause", "DSISR", "DAR", "PT hashmask"};

CRegTable::CRegTable()
{
m_formatRegs.fill(FormatSpecifier::Hex8);

for (auto& entry : m_formatFRegs)
entry.fill(FormatSpecifier::Hex16);

memset(m_CachedRegs, 0, sizeof(m_CachedRegs));
memset(m_CachedSpecialRegs, 0, sizeof(m_CachedSpecialRegs));
memset(m_CachedFRegs, 0, sizeof(m_CachedFRegs));
memset(m_CachedRegHasChanged, 0, sizeof(m_CachedRegHasChanged));
memset(m_CachedSpecialRegHasChanged, 0, sizeof(m_CachedSpecialRegHasChanged));
memset(m_CachedFRegHasChanged, 0, sizeof(m_CachedFRegHasChanged));
}

wxString CRegTable::GetFormatString(FormatSpecifier specifier)
{
switch (specifier)
{
case FormatSpecifier::Hex8:
return wxString("%08x");
case FormatSpecifier::Hex16:
return wxString("%016llx");
case FormatSpecifier::Float:
return wxString("%g");
case FormatSpecifier::Double:
return wxString("%g");
case FormatSpecifier::UInt:
return wxString("%u");
case FormatSpecifier::Int:
return wxString("%i");
default:
return wxString("");
}
}

wxString CRegTable::FormatGPR(int reg_index)
{
if (m_formatRegs[reg_index] == FormatSpecifier::Int)
{
return wxString::Format(GetFormatString(m_formatRegs[reg_index]),
static_cast<s32>(GPR(reg_index)));
}
if (m_formatRegs[reg_index] == FormatSpecifier::Float)
{
float value;
std::memcpy(&value, &GPR(reg_index), sizeof(float));
return wxString::Format(GetFormatString(m_formatRegs[reg_index]), value);
}
return wxString::Format(GetFormatString(m_formatRegs[reg_index]), GPR(reg_index));
}

wxString CRegTable::FormatFPR(int reg_index, int reg_part)
{
if (m_formatFRegs[reg_index][reg_part] == FormatSpecifier::Double)
{
double reg = (reg_part == 0) ? rPS0(reg_index) : rPS1(reg_index);
return wxString::Format(GetFormatString(m_formatFRegs[reg_index][reg_part]), reg);
}
u64 reg = (reg_part == 0) ? riPS0(reg_index) : riPS1(reg_index);
return wxString::Format(GetFormatString(m_formatFRegs[reg_index][reg_part]), reg);
}

static u32 GetSpecialRegValue(int reg)
bool CRegTable::TryParseGPR(wxString str, FormatSpecifier format, u32* value)
{
if (format == FormatSpecifier::Hex8)
{
unsigned long val;
if (str.ToCULong(&val, 16))
{
*value = static_cast<u32>(val);
return true;
}
return false;
}
if (format == FormatSpecifier::Int)
{
long signed_val;
if (str.ToCLong(&signed_val))
{
*value = static_cast<u32>(signed_val);
return true;
}
return false;
}
if (format == FormatSpecifier::UInt)
{
unsigned long val;
if (str.ToCULong(&val))
{
*value = static_cast<u32>(val);
return true;
}
return false;
}
if (format == FormatSpecifier::Float)
{
double double_val;
if (str.ToCDouble(&double_val))
{
float float_val = static_cast<float>(double_val);
std::memcpy(value, &float_val, sizeof(float));
return true;
}
return false;
}
return false;
}

bool CRegTable::TryParseFPR(wxString str, FormatSpecifier format, unsigned long long* value)
{
if (format == FormatSpecifier::Hex16)
{
return str.ToULongLong(value, 16);
}
if (format == FormatSpecifier::Double)
{
double double_val;
if (str.ToCDouble(&double_val))
{
std::memcpy(value, &double_val, sizeof(u64));
return true;
}
return false;
}
return false;
}

void CRegTable::SetRegisterFormat(int col, int row, FormatSpecifier specifier)
{
if (row >= 32)
return;

switch (col)
{
case 1:
m_formatRegs[row] = specifier;
return;
case 3:
m_formatFRegs[row][0] = specifier;
return;
case 4:
m_formatFRegs[row][1] = specifier;
return;
}
}

u32 CRegTable::GetSpecialRegValue(int reg)
{
switch (reg)
{
Expand Down Expand Up @@ -71,7 +234,7 @@ static u32 GetSpecialRegValue(int reg)
}
}

static wxString GetValueByRowCol(int row, int col)
wxString CRegTable::GetValue(int row, int col)
{
if (row < 32)
{
Expand All @@ -80,13 +243,13 @@ static wxString GetValueByRowCol(int row, int col)
case 0:
return StrToWxStr(GekkoDisassembler::GetGPRName(row));
case 1:
return wxString::Format("%08x", GPR(row));
return FormatGPR(row);
case 2:
return StrToWxStr(GekkoDisassembler::GetFPRName(row));
case 3:
return wxString::Format("%016llx", riPS0(row));
return FormatFPR(row, 0);
case 4:
return wxString::Format("%016llx", riPS1(row));
return FormatFPR(row, 1);
case 5:
{
if (row < 4)
Expand Down Expand Up @@ -162,12 +325,7 @@ static wxString GetValueByRowCol(int row, int col)
return wxEmptyString;
}

wxString CRegTable::GetValue(int row, int col)
{
return GetValueByRowCol(row, col);
}

static void SetSpecialRegValue(int reg, u32 value)
void CRegTable::SetSpecialRegValue(int reg, u32 value)
{
switch (reg)
{
Expand Down Expand Up @@ -216,24 +374,34 @@ static void SetSpecialRegValue(int reg, u32 value)

void CRegTable::SetValue(int row, int col, const wxString& strNewVal)
{
u32 newVal = 0;
if (TryParse("0x" + WxStrToStr(strNewVal), &newVal))
if (row < 32)
{
if (row < 32)
if (col == 1)
{
if (col == 1)
GPR(row) = newVal;
else if (col == 3)
riPS0(row) = newVal;
else if (col == 4)
riPS1(row) = newVal;
u32 new_val = 0;
if (TryParseGPR(strNewVal, m_formatRegs[row], &new_val))
GPR(row) = new_val;
}
else
else if (col == 3)
{
if ((row - 32 < NUM_SPECIALS) && (col == 1))
{
SetSpecialRegValue(row - 32, newVal);
}
unsigned long long new_val = 0;
if (TryParseFPR(strNewVal, m_formatFRegs[row][0], &new_val))
riPS0(row) = new_val;
}
else if (col == 4)
{
unsigned long long new_val = 0;
if (TryParseFPR(strNewVal, m_formatFRegs[row][1], &new_val))
riPS1(row) = new_val;
}
}
else
{
if ((row - 32 < NUM_SPECIALS) && (col == 1))
{
u32 new_val = 0;
if (TryParse("0x" + WxStrToStr(strNewVal), &new_val))
SetSpecialRegValue(row - 32, new_val);
}
}
}
Expand Down Expand Up @@ -318,16 +486,33 @@ void CRegisterView::Update()
void CRegisterView::OnMouseDownR(wxGridEvent& event)
{
// popup menu
int row = event.GetRow();
int col = event.GetCol();
m_selectedRow = event.GetRow();
m_selectedColumn = event.GetCol();

wxString strNewVal = GetValueByRowCol(row, col);
wxString strNewVal = m_register_table->GetValue(m_selectedRow, m_selectedColumn);
TryParse("0x" + WxStrToStr(strNewVal), &m_selectedAddress);

wxMenu menu;
menu.Append(IDM_WATCHADDRESS, _("Add to &watch"));
menu.Append(IDM_VIEWMEMORY, _("View &memory"));
menu.Append(IDM_VIEWCODE, _("View &code"));
if (m_selectedRow < 32 &&
(m_selectedColumn == 1 || m_selectedColumn == 3 || m_selectedColumn == 4))
{
menu.AppendSeparator();
if (m_selectedColumn == 1)
{
menu.Append(IDM_VIEW_HEX8, _("View as hexadecimal"));
menu.Append(IDM_VIEW_INT, _("View as signed integer"));
menu.Append(IDM_VIEW_UINT, _("View as unsigned integer"));
menu.Append(IDM_VIEW_FLOAT, _("View as float"));
}
else
{
menu.Append(IDM_VIEW_HEX16, _("View as hexadecimal"));
menu.Append(IDM_VIEW_DOUBLE, _("View as double"));
}
}
PopupMenu(&menu);
}

Expand Down Expand Up @@ -355,6 +540,30 @@ void CRegisterView::OnPopupMenu(wxCommandEvent& event)
code_window->JumpToAddress(m_selectedAddress);
Refresh();
break;
case IDM_VIEW_HEX8:
m_register_table->SetRegisterFormat(m_selectedColumn, m_selectedRow, FormatSpecifier::Hex8);
Refresh();
break;
case IDM_VIEW_HEX16:
m_register_table->SetRegisterFormat(m_selectedColumn, m_selectedRow, FormatSpecifier::Hex16);
Refresh();
break;
case IDM_VIEW_INT:
m_register_table->SetRegisterFormat(m_selectedColumn, m_selectedRow, FormatSpecifier::Int);
Refresh();
break;
case IDM_VIEW_UINT:
m_register_table->SetRegisterFormat(m_selectedColumn, m_selectedRow, FormatSpecifier::UInt);
Refresh();
break;
case IDM_VIEW_FLOAT:
m_register_table->SetRegisterFormat(m_selectedColumn, m_selectedRow, FormatSpecifier::Float);
Refresh();
break;
case IDM_VIEW_DOUBLE:
m_register_table->SetRegisterFormat(m_selectedColumn, m_selectedRow, FormatSpecifier::Double);
Refresh();
break;
}
event.Skip();
}

0 comments on commit ea2effc

Please sign in to comment.