Skip to content

Commit

Permalink
Merge pull request #4178 from aldelaro5/registerView-formated-display
Browse files Browse the repository at this point in the history
Add formatting options for the GPR and FPR registers
  • Loading branch information
lioncash committed Sep 13, 2016
2 parents bdcee1c + ea2effc commit add5de2
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
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 add5de2

Please sign in to comment.