Debugger: Add SIMD format options.
RegisterTableModel: - Add member for preferred SIMD unit format, and use it to decide what to divide up such registers as, rather than hardcoding 16 bit integer. RegistersView: - When right clicking on an SIMD register, display a format context menu allowing the user to decide what packed unit format to interpret the register data as, and adjust table model accordingly.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009-2012, Ingo Weinhold, [email protected].
|
* Copyright 2009-2012, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2011-2013, Rene Gollent, [email protected].
|
* Copyright 2011-2015, Rene Gollent, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -26,6 +26,43 @@
|
|||||||
#include "UiUtils.h"
|
#include "UiUtils.h"
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MSG_SIMD_RENDER_FORMAT_CHANGED = 'srfc'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SIMD_RENDER_FORMAT_INT8 = 0,
|
||||||
|
SIMD_RENDER_FORMAT_INT16,
|
||||||
|
SIMD_RENDER_FORMAT_INT32,
|
||||||
|
SIMD_RENDER_FORMAT_INT64,
|
||||||
|
SIMD_RENDER_FORMAT_FLOAT,
|
||||||
|
SIMD_RENDER_FORMAT_DOUBLE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
GetLabelForSIMDFormat(int format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case SIMD_RENDER_FORMAT_INT8:
|
||||||
|
return "8-bit integer";
|
||||||
|
case SIMD_RENDER_FORMAT_INT16:
|
||||||
|
return "16-bit integer";
|
||||||
|
case SIMD_RENDER_FORMAT_INT32:
|
||||||
|
return "32-bit integer";
|
||||||
|
case SIMD_RENDER_FORMAT_INT64:
|
||||||
|
return "64-bit integer";
|
||||||
|
case SIMD_RENDER_FORMAT_FLOAT:
|
||||||
|
return "Float";
|
||||||
|
case SIMD_RENDER_FORMAT_DOUBLE:
|
||||||
|
return "Double";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - RegisterValueColumn
|
// #pragma mark - RegisterValueColumn
|
||||||
|
|
||||||
|
|
||||||
@@ -92,7 +129,8 @@ public:
|
|||||||
RegisterTableModel(Architecture* architecture)
|
RegisterTableModel(Architecture* architecture)
|
||||||
:
|
:
|
||||||
fArchitecture(architecture),
|
fArchitecture(architecture),
|
||||||
fCpuState(NULL)
|
fCpuState(NULL),
|
||||||
|
fSIMDFormat(SIMD_RENDER_FORMAT_INT16)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,6 +155,11 @@ public:
|
|||||||
return fArchitecture->CountRegisters();
|
return fArchitecture->CountRegisters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int32 SIMDRenderFormat() const
|
||||||
|
{
|
||||||
|
return fSIMDFormat;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, BVariant& value)
|
virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, BVariant& value)
|
||||||
{
|
{
|
||||||
if (rowIndex < 0 || rowIndex >= fArchitecture->CountRegisters())
|
if (rowIndex < 0 || rowIndex >= fArchitecture->CountRegisters())
|
||||||
@@ -141,18 +184,49 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSIMDFormat(int32 format)
|
||||||
|
{
|
||||||
|
if (fSIMDFormat != format) {
|
||||||
|
fSIMDFormat = format;
|
||||||
|
NotifyRowsChanged(0, CountRows());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _FormatSIMDValue(const Register* reg, BVariant& _value)
|
void _FormatSIMDValue(const Register* reg, BVariant& _value)
|
||||||
{
|
{
|
||||||
// for now, format SIMD registers as groups of 16-bit integer values.
|
|
||||||
// TODO: support multiple formats.
|
|
||||||
BString temp("{");
|
BString temp("{");
|
||||||
uint16* data = (uint16*)_value.ToPointer();
|
char* data = (char*)_value.ToPointer();
|
||||||
uint32 count = reg->BitSize() / (sizeof(uint16) * 8);
|
uint32 count = reg->BitSize() / (_GetSIMDFormatByteSize() * 8);
|
||||||
for (uint32 i = 0; i < count; i++) {
|
for (uint32 i = 0; i < count; i ++) {
|
||||||
BString intFormat;
|
BString format;
|
||||||
intFormat.SetToFormat("%#" B_PRIx16, data[i]);
|
switch (fSIMDFormat) {
|
||||||
temp += intFormat;
|
case SIMD_RENDER_FORMAT_INT8:
|
||||||
|
format.SetToFormat("%#" B_PRIx8,
|
||||||
|
_GetSIMDValueAtOffset<uint8>(data, i));
|
||||||
|
break;
|
||||||
|
case SIMD_RENDER_FORMAT_INT16:
|
||||||
|
format.SetToFormat("%#" B_PRIx16,
|
||||||
|
_GetSIMDValueAtOffset<uint16>(data, i));
|
||||||
|
break;
|
||||||
|
case SIMD_RENDER_FORMAT_INT32:
|
||||||
|
format.SetToFormat("%#" B_PRIx32,
|
||||||
|
_GetSIMDValueAtOffset<uint32>(data, i));
|
||||||
|
break;
|
||||||
|
case SIMD_RENDER_FORMAT_INT64:
|
||||||
|
format.SetToFormat("%#" B_PRIx64,
|
||||||
|
_GetSIMDValueAtOffset<uint64>(data, i));
|
||||||
|
break;
|
||||||
|
case SIMD_RENDER_FORMAT_FLOAT:
|
||||||
|
format.SetToFormat("%.3g",
|
||||||
|
(double)_GetSIMDValueAtOffset<float>(data, i));
|
||||||
|
break;
|
||||||
|
case SIMD_RENDER_FORMAT_DOUBLE:
|
||||||
|
format.SetToFormat("%.3g",
|
||||||
|
_GetSIMDValueAtOffset<double>(data, i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
temp += format;
|
||||||
if (i < count - 1)
|
if (i < count - 1)
|
||||||
temp += ", ";
|
temp += ", ";
|
||||||
}
|
}
|
||||||
@@ -161,9 +235,36 @@ private:
|
|||||||
_value.SetTo(temp);
|
_value.SetTo(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T _GetSIMDValueAtOffset(char* data, int32 index)
|
||||||
|
{
|
||||||
|
return ((T*)data)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 _GetSIMDFormatByteSize() const
|
||||||
|
{
|
||||||
|
switch (fSIMDFormat) {
|
||||||
|
case SIMD_RENDER_FORMAT_INT8:
|
||||||
|
return sizeof(char);
|
||||||
|
case SIMD_RENDER_FORMAT_INT16:
|
||||||
|
return sizeof(int16);
|
||||||
|
case SIMD_RENDER_FORMAT_INT32:
|
||||||
|
return sizeof(int32);
|
||||||
|
case SIMD_RENDER_FORMAT_INT64:
|
||||||
|
return sizeof(int64);
|
||||||
|
case SIMD_RENDER_FORMAT_FLOAT:
|
||||||
|
return sizeof(float);
|
||||||
|
case SIMD_RENDER_FORMAT_DOUBLE:
|
||||||
|
return sizeof(double);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Architecture* fArchitecture;
|
Architecture* fArchitecture;
|
||||||
CpuState* fCpuState;
|
CpuState* fCpuState;
|
||||||
|
int32 fSIMDFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -206,6 +307,27 @@ RegistersView::Create(Architecture* architecture)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RegistersView::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case MSG_SIMD_RENDER_FORMAT_CHANGED:
|
||||||
|
{
|
||||||
|
int32 format;
|
||||||
|
if (message->FindInt32("format", &format) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
fRegisterTableModel->SetSIMDFormat(format);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
BGroupView::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RegistersView::SetCpuState(CpuState* cpuState)
|
RegistersView::SetCpuState(CpuState* cpuState)
|
||||||
{
|
{
|
||||||
@@ -260,6 +382,9 @@ void
|
|||||||
RegistersView::TableCellMouseDown(Table* table, int32 rowIndex,
|
RegistersView::TableCellMouseDown(Table* table, int32 rowIndex,
|
||||||
int32 columnIndex, BPoint screenWhere, uint32 buttons)
|
int32 columnIndex, BPoint screenWhere, uint32 buttons)
|
||||||
{
|
{
|
||||||
|
if (rowIndex < 0 || rowIndex >= fArchitecture->CountRegisters())
|
||||||
|
return;
|
||||||
|
|
||||||
if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0)
|
if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -267,29 +392,65 @@ RegistersView::TableCellMouseDown(Table* table, int32 rowIndex,
|
|||||||
if (!fRegisterTableModel->GetValueAt(rowIndex, 1, value))
|
if (!fRegisterTableModel->GetValueAt(rowIndex, 1, value))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BPopUpMenu* menu = new(std::nothrow)BPopUpMenu("Options");
|
const Register* reg = fArchitecture->Registers() + rowIndex;
|
||||||
|
if (reg->Format() == REGISTER_FORMAT_FLOAT) {
|
||||||
|
// for floating point registers, we currently have no
|
||||||
|
// context menu options to display.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BPopUpMenu* menu = new(std::nothrow) BPopUpMenu("Options");
|
||||||
if (menu == NULL)
|
if (menu == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ObjectDeleter<BPopUpMenu> menuDeleter(menu);
|
ObjectDeleter<BPopUpMenu> menuDeleter(menu);
|
||||||
BMessage* message = new(std::nothrow)BMessage(MSG_SHOW_INSPECTOR_WINDOW);
|
|
||||||
if (message == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
message->AddUInt64("address", value.ToUInt64());
|
if (reg->Format() == REGISTER_FORMAT_INTEGER) {
|
||||||
|
BMessage* message = new(std::nothrow) BMessage(MSG_SHOW_INSPECTOR_WINDOW);
|
||||||
|
if (message == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
ObjectDeleter<BMessage> messageDeleter(message);
|
message->AddUInt64("address", value.ToUInt64());
|
||||||
BMenuItem* item = new(std::nothrow)BMenuItem("Inspect", message);
|
|
||||||
if (item == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
messageDeleter.Detach();
|
ObjectDeleter<BMessage> messageDeleter(message);
|
||||||
ObjectDeleter<BMenuItem> itemDeleter(item);
|
BMenuItem* item = new(std::nothrow) BMenuItem("Inspect", message);
|
||||||
if (!menu->AddItem(item))
|
if (item == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
messageDeleter.Detach();
|
||||||
|
ObjectDeleter<BMenuItem> itemDeleter(item);
|
||||||
|
if (!menu->AddItem(item))
|
||||||
|
return;
|
||||||
|
|
||||||
|
itemDeleter.Detach();
|
||||||
|
|
||||||
|
item->SetTarget(Window());
|
||||||
|
} else if (reg->Format() == REGISTER_FORMAT_SIMD) {
|
||||||
|
BMenu* formatMenu = new(std::nothrow) BMenu("Format");
|
||||||
|
if (formatMenu == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ObjectDeleter<BMenu> formatMenuDeleter(formatMenu);
|
||||||
|
if (!menu->AddItem(formatMenu))
|
||||||
|
return;
|
||||||
|
formatMenuDeleter.Detach();
|
||||||
|
|
||||||
|
if (_AddFormatItem(formatMenu, SIMD_RENDER_FORMAT_INT8) != B_OK)
|
||||||
|
return;
|
||||||
|
if (_AddFormatItem(formatMenu, SIMD_RENDER_FORMAT_INT16) != B_OK)
|
||||||
|
return;
|
||||||
|
if (_AddFormatItem(formatMenu, SIMD_RENDER_FORMAT_INT32) != B_OK)
|
||||||
|
return;
|
||||||
|
if (_AddFormatItem(formatMenu, SIMD_RENDER_FORMAT_INT64) != B_OK)
|
||||||
|
return;
|
||||||
|
if (_AddFormatItem(formatMenu, SIMD_RENDER_FORMAT_FLOAT) != B_OK)
|
||||||
|
return;
|
||||||
|
if (_AddFormatItem(formatMenu, SIMD_RENDER_FORMAT_DOUBLE) != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
formatMenu->SetTargetForItems(this);
|
||||||
|
}
|
||||||
|
|
||||||
itemDeleter.Detach();
|
|
||||||
menu->SetTargetForItems(Window());
|
|
||||||
menuDeleter.Detach();
|
menuDeleter.Detach();
|
||||||
|
|
||||||
BRect mouseRect(screenWhere, screenWhere);
|
BRect mouseRect(screenWhere, screenWhere);
|
||||||
@@ -319,3 +480,36 @@ RegistersView::_Init()
|
|||||||
|
|
||||||
fRegisterTable->AddTableListener(this);
|
fRegisterTable->AddTableListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RegistersView::_AddFormatItem(BMenu* menu, int32 format)
|
||||||
|
{
|
||||||
|
BMessage* message = new(std::nothrow) BMessage(
|
||||||
|
MSG_SIMD_RENDER_FORMAT_CHANGED);
|
||||||
|
if (message == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
ObjectDeleter<BMessage> messageDeleter(message);
|
||||||
|
if (message->AddInt32("format", format) != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
BMenuItem* item = new(std::nothrow) BMenuItem(
|
||||||
|
GetLabelForSIMDFormat(format), message);
|
||||||
|
if (item == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
messageDeleter.Detach();
|
||||||
|
ObjectDeleter<BMenuItem> itemDeleter(item);
|
||||||
|
if (!menu->AddItem(item))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
itemDeleter.Detach();
|
||||||
|
|
||||||
|
if (format == fRegisterTableModel->SIMDRenderFormat())
|
||||||
|
item->SetMarked(true);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2013, Rene Gollent, [email protected].
|
* Copyright 2013-2015, Rene Gollent, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef REGISTERS_VIEW_H
|
#ifndef REGISTERS_VIEW_H
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class Architecture;
|
class Architecture;
|
||||||
|
class BMenu;
|
||||||
|
|
||||||
|
|
||||||
class RegistersView : public BGroupView, private TableListener {
|
class RegistersView : public BGroupView, private TableListener {
|
||||||
@@ -23,6 +24,8 @@ public:
|
|||||||
static RegistersView* Create(Architecture* architecture);
|
static RegistersView* Create(Architecture* architecture);
|
||||||
// throws
|
// throws
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
void SetCpuState(CpuState* cpuState);
|
void SetCpuState(CpuState* cpuState);
|
||||||
|
|
||||||
void LoadSettings(const BMessage& settings);
|
void LoadSettings(const BMessage& settings);
|
||||||
@@ -41,6 +44,7 @@ private:
|
|||||||
uint32 buttons);
|
uint32 buttons);
|
||||||
|
|
||||||
void _Init();
|
void _Init();
|
||||||
|
status_t _AddFormatItem(BMenu* menu, int32 format);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Architecture* fArchitecture;
|
Architecture* fArchitecture;
|
||||||
|
|||||||
Reference in New Issue
Block a user