From 87c56aed03c7bcf2c4b18a7a170d79d8787a6799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Jun 2024 12:13:10 +0200 Subject: [PATCH] Split of the JitCompareScreen into its own files --- CMakeLists.txt | 2 + UI/DevScreens.cpp | 362 +---------------------------- UI/DevScreens.h | 59 ----- UI/JitCompareScreen.cpp | 369 ++++++++++++++++++++++++++++++ UI/JitCompareScreen.h | 60 +++++ UI/UI.vcxproj | 2 + UI/UI.vcxproj.filters | 6 + UWP/UI_UWP/UI_UWP.vcxproj | 2 + UWP/UI_UWP/UI_UWP.vcxproj.filters | 2 + android/jni/Android.mk | 1 + 10 files changed, 445 insertions(+), 420 deletions(-) create mode 100644 UI/JitCompareScreen.cpp create mode 100644 UI/JitCompareScreen.h diff --git a/CMakeLists.txt b/CMakeLists.txt index db1ee1534e..f62b8f3560 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1554,6 +1554,8 @@ list(APPEND NativeAppSource UI/CwCheatScreen.cpp UI/InstallZipScreen.h UI/InstallZipScreen.cpp + UI/JitCompareScreen.h + UI/JitCompareScreen.cpp UI/MemStickScreen.h UI/MemStickScreen.cpp UI/ProfilerDraw.h diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index a9f34766aa..afd9ad7508 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -69,6 +69,7 @@ #include "UI/MainScreen.h" #include "UI/ControlMappingScreen.h" #include "UI/GameSettingsScreen.h" +#include "UI/JitCompareScreen.h" #ifdef _WIN32 // Want to avoid including the full header here as it includes d3dx.h @@ -920,367 +921,6 @@ void SystemInfoScreen::CreateInternalsTab(UI::ViewGroup *internals) { #endif } -void AddressPromptScreen::CreatePopupContents(UI::ViewGroup *parent) { - using namespace UI; - - auto dev = GetI18NCategory(I18NCat::DEVELOPER); - - addrView_ = new TextView(dev->T("Enter address"), ALIGN_HCENTER, false); - parent->Add(addrView_); - - ViewGroup *grid = new GridLayout(GridLayoutSettings(60, 40)); - parent->Add(grid); - - for (int i = 0; i < 16; ++i) { - char temp[16]; - snprintf(temp, 16, " %X ", i); - buttons_[i] = new Button(temp); - grid->Add(buttons_[i])->OnClick.Handle(this, &AddressPromptScreen::OnDigitButton); - } - - parent->Add(new Button(dev->T("Backspace")))->OnClick.Handle(this, &AddressPromptScreen::OnBackspace); -} - -void AddressPromptScreen::OnCompleted(DialogResult result) { - if (result == DR_OK) { - UI::EventParams e{}; - e.v = root_; - e.a = addr_; - OnChoice.Trigger(e); - } -} - -UI::EventReturn AddressPromptScreen::OnDigitButton(UI::EventParams &e) { - for (int i = 0; i < 16; ++i) { - if (buttons_[i] == e.v) { - AddDigit(i); - } - } - return UI::EVENT_DONE; -} - -UI::EventReturn AddressPromptScreen::OnBackspace(UI::EventParams &e) { - BackspaceDigit(); - return UI::EVENT_DONE; -} - -void AddressPromptScreen::AddDigit(int n) { - if ((addr_ & 0xF0000000) == 0) { - addr_ = addr_ * 16 + n; - } - UpdatePreviewDigits(); -} - -void AddressPromptScreen::BackspaceDigit() { - addr_ /= 16; - UpdatePreviewDigits(); -} - -void AddressPromptScreen::UpdatePreviewDigits() { - if (addr_ != 0) { - char temp[32]; - snprintf(temp, 32, "%8X", addr_); - addrView_->SetText(temp); - } else { - auto dev = GetI18NCategory(I18NCat::DEVELOPER); - addrView_->SetText(dev->T("Enter address")); - } -} - -bool AddressPromptScreen::key(const KeyInput &key) { - if (key.flags & KEY_DOWN) { - if (key.keyCode >= NKCODE_0 && key.keyCode <= NKCODE_9) { - AddDigit(key.keyCode - NKCODE_0); - } else if (key.keyCode >= NKCODE_A && key.keyCode <= NKCODE_F) { - AddDigit(10 + key.keyCode - NKCODE_A); - // NKCODE_DEL is backspace. - } else if (key.keyCode == NKCODE_DEL) { - BackspaceDigit(); - } else if (key.keyCode == NKCODE_ENTER) { - TriggerFinish(DR_OK); - } else { - return UIDialogScreen::key(key); - } - } else { - return UIDialogScreen::key(key); - } - return true; -} - -// Three panes: Block chooser, MIPS view, ARM/x86 view -void JitCompareScreen::CreateViews() { - auto di = GetI18NCategory(I18NCat::DIALOG); - auto dev = GetI18NCategory(I18NCat::DEVELOPER); - - using namespace UI; - - root_ = new LinearLayout(ORIENT_HORIZONTAL); - - ScrollView *leftColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); - LinearLayout *leftColumn = leftColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); - - ScrollView *midColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(2.0f))); - LinearLayout *midColumn = midColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); - midColumn->SetTag("JitCompareLeftDisasm"); - leftDisasm_ = midColumn->Add(new LinearLayout(ORIENT_VERTICAL)); - leftDisasm_->SetSpacing(0.0f); - - ScrollView *rightColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(2.0f))); - rightColumnScroll->SetTag("JitCompareRightDisasm"); - LinearLayout *rightColumn = rightColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); - rightDisasm_ = rightColumn->Add(new LinearLayout(ORIENT_VERTICAL)); - rightDisasm_->SetSpacing(0.0f); - - leftColumn->Add(new Choice(dev->T("Current")))->OnClick.Handle(this, &JitCompareScreen::OnCurrentBlock); - leftColumn->Add(new Choice(dev->T("By Address")))->OnClick.Handle(this, &JitCompareScreen::OnSelectBlock); - leftColumn->Add(new Choice(dev->T("Prev")))->OnClick.Handle(this, &JitCompareScreen::OnPrevBlock); - leftColumn->Add(new Choice(dev->T("Next")))->OnClick.Handle(this, &JitCompareScreen::OnNextBlock); - leftColumn->Add(new Choice(dev->T("Random")))->OnClick.Handle(this, &JitCompareScreen::OnRandomBlock); - leftColumn->Add(new Choice(dev->T("FPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomFPUBlock); - leftColumn->Add(new Choice(dev->T("VFPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomVFPUBlock); - leftColumn->Add(new Choice(dev->T("Stats")))->OnClick.Handle(this, &JitCompareScreen::OnShowStats); - leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); - blockName_ = leftColumn->Add(new TextView(dev->T("No block"))); - blockAddr_ = leftColumn->Add(new TextEdit("", dev->T("Block address"), "", new LayoutParams(FILL_PARENT, WRAP_CONTENT))); - blockAddr_->OnTextChange.Handle(this, &JitCompareScreen::OnAddressChange); - blockStats_ = leftColumn->Add(new TextView("")); - - EventParams ignore{}; - OnCurrentBlock(ignore); -} - -void JitCompareScreen::UpdateDisasm() { - leftDisasm_->Clear(); - rightDisasm_->Clear(); - - using namespace UI; - - if (!MIPSComp::jit) { - return; - } - - JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); - if (!blockCacheDebug->IsValidBlock(currentBlock_)) { - return; - } - - char temp[256]; - snprintf(temp, sizeof(temp), "%i/%i", currentBlock_, blockCacheDebug->GetNumBlocks()); - blockName_->SetText(temp); - - if (currentBlock_ < 0 || !blockCacheDebug || currentBlock_ >= blockCacheDebug->GetNumBlocks()) { - auto dev = GetI18NCategory(I18NCat::DEVELOPER); - leftDisasm_->Add(new TextView(dev->T("No block"))); - rightDisasm_->Add(new TextView(dev->T("No block"))); - blockStats_->SetText(""); - return; - } - - JitBlockDebugInfo debugInfo = blockCacheDebug->GetBlockDebugInfo(currentBlock_); - - snprintf(temp, sizeof(temp), "%08x", debugInfo.originalAddress); - blockAddr_->SetText(temp); - - // Alright. First generate the MIPS disassembly. - - // TODO: Need a way to communicate branch continuing. - for (const auto &line : debugInfo.origDisasm) { - leftDisasm_->Add(new TextView(line))->SetFocusable(true); - } - - // TODO : When we have both target and IR, need a third column. - if (debugInfo.targetDisasm.size()) { - for (const auto &line : debugInfo.targetDisasm) { - rightDisasm_->Add(new TextView(line))->SetFocusable(true); - } - } else { - for (const auto &line : debugInfo.irDisasm) { - rightDisasm_->Add(new TextView(line))->SetFocusable(true); - } - } - - int numMips = leftDisasm_->GetNumSubviews(); - int numHost = rightDisasm_->GetNumSubviews(); - - snprintf(temp, sizeof(temp), "%d to %d : %d%%", numMips, numHost, 100 * numHost / numMips); - blockStats_->SetText(temp); -} - -UI::EventReturn JitCompareScreen::OnAddressChange(UI::EventParams &e) { - std::lock_guard guard(MIPSComp::jitLock); - if (!MIPSComp::jit) { - return UI::EVENT_DONE; - } - JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); - if (!blockCache) - return UI::EVENT_DONE; - u32 addr; - if (blockAddr_->GetText().size() > 8) - return UI::EVENT_DONE; - if (1 == sscanf(blockAddr_->GetText().c_str(), "%08x", &addr)) { - if (Memory::IsValidAddress(addr)) { - currentBlock_ = blockCache->GetBlockNumberFromStartAddress(addr); - UpdateDisasm(); - } - } - return UI::EVENT_DONE; -} - -UI::EventReturn JitCompareScreen::OnShowStats(UI::EventParams &e) { - std::lock_guard guard(MIPSComp::jitLock); - if (!MIPSComp::jit) { - return UI::EVENT_DONE; - } - - JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); - if (!blockCache) - return UI::EVENT_DONE; - - BlockCacheStats bcStats; - blockCache->ComputeStats(bcStats); - NOTICE_LOG(JIT, "Num blocks: %i", bcStats.numBlocks); - NOTICE_LOG(JIT, "Average Bloat: %0.2f%%", 100 * bcStats.avgBloat); - NOTICE_LOG(JIT, "Min Bloat: %0.2f%% (%08x)", 100 * bcStats.minBloat, bcStats.minBloatBlock); - NOTICE_LOG(JIT, "Max Bloat: %0.2f%% (%08x)", 100 * bcStats.maxBloat, bcStats.maxBloatBlock); - - int ctr = 0, sz = (int)bcStats.bloatMap.size(); - for (auto iter : bcStats.bloatMap) { - if (ctr < 10 || ctr > sz - 10) { - NOTICE_LOG(JIT, "%08x: %f", iter.second, iter.first); - } else if (ctr == 10) { - NOTICE_LOG(JIT, "..."); - } - ctr++; - } - return UI::EVENT_DONE; -} - - -UI::EventReturn JitCompareScreen::OnSelectBlock(UI::EventParams &e) { - auto dev = GetI18NCategory(I18NCat::DEVELOPER); - - auto addressPrompt = new AddressPromptScreen(dev->T("Block address")); - addressPrompt->OnChoice.Handle(this, &JitCompareScreen::OnBlockAddress); - screenManager()->push(addressPrompt); - return UI::EVENT_DONE; -} - -UI::EventReturn JitCompareScreen::OnPrevBlock(UI::EventParams &e) { - currentBlock_--; - UpdateDisasm(); - return UI::EVENT_DONE; -} - -UI::EventReturn JitCompareScreen::OnNextBlock(UI::EventParams &e) { - currentBlock_++; - UpdateDisasm(); - return UI::EVENT_DONE; -} - -UI::EventReturn JitCompareScreen::OnBlockAddress(UI::EventParams &e) { - std::lock_guard guard(MIPSComp::jitLock); - if (!MIPSComp::jit) { - return UI::EVENT_DONE; - } - - JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); - if (!blockCache) - return UI::EVENT_DONE; - - if (Memory::IsValidAddress(e.a)) { - currentBlock_ = blockCache->GetBlockNumberFromStartAddress(e.a); - } else { - currentBlock_ = -1; - } - UpdateDisasm(); - return UI::EVENT_DONE; -} - -UI::EventReturn JitCompareScreen::OnRandomBlock(UI::EventParams &e) { - std::lock_guard guard(MIPSComp::jitLock); - if (!MIPSComp::jit) { - return UI::EVENT_DONE; - } - - JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); - if (!blockCache) - return UI::EVENT_DONE; - - int numBlocks = blockCache->GetNumBlocks(); - if (numBlocks > 0) { - int tries = 100; - while (tries-- > 0) { - currentBlock_ = rand() % numBlocks; - if (blockCache->IsValidBlock(currentBlock_)) { - break; - } - } - } - UpdateDisasm(); - return UI::EVENT_DONE; -} - -UI::EventReturn JitCompareScreen::OnRandomVFPUBlock(UI::EventParams &e) { - OnRandomBlock(IS_VFPU); - return UI::EVENT_DONE; -} - -UI::EventReturn JitCompareScreen::OnRandomFPUBlock(UI::EventParams &e) { - OnRandomBlock(IS_FPU); - return UI::EVENT_DONE; -} - -void JitCompareScreen::OnRandomBlock(int flag) { - std::lock_guard guard(MIPSComp::jitLock); - if (!MIPSComp::jit) { - return; - } - JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); - if (!blockCache) - return; - - int numBlocks = blockCache->GetNumBlocks(); - if (numBlocks > 0) { - bool anyWanted = false; - int tries = 0; - while (!anyWanted && tries < numBlocks) { - currentBlock_ = rand() % numBlocks; - if (blockCache->IsValidBlock(currentBlock_)) { - JitBlockDebugInfo b = blockCache->GetBlockDebugInfo(currentBlock_); - u32 mipsBytes = (u32)b.origDisasm.size() * 4; - for (u32 addr = b.originalAddress; addr < b.originalAddress + mipsBytes; addr += 4) { - MIPSOpcode opcode = Memory::Read_Instruction(addr); - if (MIPSGetInfo(opcode) & flag) { - char temp[256]; - MIPSDisAsm(opcode, addr, temp, sizeof(temp)); - // INFO_LOG(HLE, "Stopping at random instruction: %08x %s", addr, temp); - anyWanted = true; - break; - } - } - } - tries++; - } - - if (!anyWanted) - currentBlock_ = -1; - } - UpdateDisasm(); -} - -UI::EventReturn JitCompareScreen::OnCurrentBlock(UI::EventParams &e) { - std::lock_guard guard(MIPSComp::jitLock); - if (!MIPSComp::jit) { - return UI::EVENT_DONE; - } - JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache(); - if (!blockCache) - return UI::EVENT_DONE; - currentBlock_ = blockCache->GetBlockNumberFromAddress(currentMIPS->pc); - UpdateDisasm(); - return UI::EVENT_DONE; -} - int ShaderListScreen::ListShaders(DebugShaderType shaderType, UI::LinearLayout *view) { using namespace UI; std::vector shaderIds_ = gpu->DebugGetShaderIDs(shaderType); diff --git a/UI/DevScreens.h b/UI/DevScreens.h index ada7c5e129..ef9965ba4d 100644 --- a/UI/DevScreens.h +++ b/UI/DevScreens.h @@ -117,34 +117,6 @@ protected: void CreateInternalsTab(UI::ViewGroup *internals); }; -class AddressPromptScreen : public PopupScreen { -public: - AddressPromptScreen(std::string_view title) : PopupScreen(title, "OK", "Cancel"), addrView_(NULL), addr_(0) { - memset(buttons_, 0, sizeof(buttons_)); - } - - const char *tag() const override { return "AddressPrompt"; } - - bool key(const KeyInput &key) override; - - UI::Event OnChoice; - -protected: - void CreatePopupContents(UI::ViewGroup *parent) override; - void OnCompleted(DialogResult result) override; - UI::EventReturn OnDigitButton(UI::EventParams &e); - UI::EventReturn OnBackspace(UI::EventParams &e); - -private: - void AddDigit(int n); - void BackspaceDigit(); - void UpdatePreviewDigits(); - - UI::TextView *addrView_; - UI::Button *buttons_[16]; - unsigned int addr_; -}; - class GPIGPOScreen : public PopupScreen { public: GPIGPOScreen(std::string_view title) : PopupScreen(title, "OK") {} @@ -154,37 +126,6 @@ protected: void CreatePopupContents(UI::ViewGroup *parent) override; }; -class JitCompareScreen : public UIDialogScreenWithBackground { -public: - void CreateViews() override; - - const char *tag() const override { return "JitCompare"; } - -private: - void UpdateDisasm(); - UI::EventReturn OnRandomBlock(UI::EventParams &e); - UI::EventReturn OnRandomFPUBlock(UI::EventParams &e); - UI::EventReturn OnRandomVFPUBlock(UI::EventParams &e); - void OnRandomBlock(int flag); - - UI::EventReturn OnCurrentBlock(UI::EventParams &e); - UI::EventReturn OnSelectBlock(UI::EventParams &e); - UI::EventReturn OnPrevBlock(UI::EventParams &e); - UI::EventReturn OnNextBlock(UI::EventParams &e); - UI::EventReturn OnBlockAddress(UI::EventParams &e); - UI::EventReturn OnAddressChange(UI::EventParams &e); - UI::EventReturn OnShowStats(UI::EventParams &e); - - int currentBlock_ = -1; - - UI::TextView *blockName_; - UI::TextEdit *blockAddr_; - UI::TextView *blockStats_; - - UI::LinearLayout *leftDisasm_; - UI::LinearLayout *rightDisasm_; -}; - class ShaderListScreen : public UIDialogScreenWithBackground { public: void CreateViews() override; diff --git a/UI/JitCompareScreen.cpp b/UI/JitCompareScreen.cpp new file mode 100644 index 0000000000..53f45a316e --- /dev/null +++ b/UI/JitCompareScreen.cpp @@ -0,0 +1,369 @@ +#include "UI/JitCompareScreen.h" + +#include "Core/MemMap.h" +#include "Core/MIPS/MIPSTables.h" +#include "Core/MIPS/JitCommon/JitBlockCache.h" +#include "Core/MIPS/JitCommon/JitCommon.h" +#include "Core/MIPS/JitCommon/JitState.h" + +// Three panes: Block chooser, MIPS view, ARM/x86 view +void JitCompareScreen::CreateViews() { + auto di = GetI18NCategory(I18NCat::DIALOG); + auto dev = GetI18NCategory(I18NCat::DEVELOPER); + + using namespace UI; + + root_ = new LinearLayout(ORIENT_HORIZONTAL); + + ScrollView *leftColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + LinearLayout *leftColumn = leftColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); + + ScrollView *midColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(2.0f))); + LinearLayout *midColumn = midColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); + midColumn->SetTag("JitCompareLeftDisasm"); + leftDisasm_ = midColumn->Add(new LinearLayout(ORIENT_VERTICAL)); + leftDisasm_->SetSpacing(0.0f); + + ScrollView *rightColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(2.0f))); + rightColumnScroll->SetTag("JitCompareRightDisasm"); + LinearLayout *rightColumn = rightColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); + rightDisasm_ = rightColumn->Add(new LinearLayout(ORIENT_VERTICAL)); + rightDisasm_->SetSpacing(0.0f); + + leftColumn->Add(new Choice(dev->T("Current")))->OnClick.Handle(this, &JitCompareScreen::OnCurrentBlock); + leftColumn->Add(new Choice(dev->T("By Address")))->OnClick.Handle(this, &JitCompareScreen::OnSelectBlock); + leftColumn->Add(new Choice(dev->T("Prev")))->OnClick.Handle(this, &JitCompareScreen::OnPrevBlock); + leftColumn->Add(new Choice(dev->T("Next")))->OnClick.Handle(this, &JitCompareScreen::OnNextBlock); + leftColumn->Add(new Choice(dev->T("Random")))->OnClick.Handle(this, &JitCompareScreen::OnRandomBlock); + leftColumn->Add(new Choice(dev->T("FPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomFPUBlock); + leftColumn->Add(new Choice(dev->T("VFPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomVFPUBlock); + leftColumn->Add(new Choice(dev->T("Stats")))->OnClick.Handle(this, &JitCompareScreen::OnShowStats); + leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); + blockName_ = leftColumn->Add(new TextView(dev->T("No block"))); + blockAddr_ = leftColumn->Add(new TextEdit("", dev->T("Block address"), "", new LayoutParams(FILL_PARENT, WRAP_CONTENT))); + blockAddr_->OnTextChange.Handle(this, &JitCompareScreen::OnAddressChange); + blockStats_ = leftColumn->Add(new TextView("")); + + EventParams ignore{}; + OnCurrentBlock(ignore); +} + +void JitCompareScreen::UpdateDisasm() { + leftDisasm_->Clear(); + rightDisasm_->Clear(); + + using namespace UI; + + if (!MIPSComp::jit) { + return; + } + + JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); + if (!blockCacheDebug->IsValidBlock(currentBlock_)) { + return; + } + + char temp[256]; + snprintf(temp, sizeof(temp), "%i/%i", currentBlock_, blockCacheDebug->GetNumBlocks()); + blockName_->SetText(temp); + + if (currentBlock_ < 0 || !blockCacheDebug || currentBlock_ >= blockCacheDebug->GetNumBlocks()) { + auto dev = GetI18NCategory(I18NCat::DEVELOPER); + leftDisasm_->Add(new TextView(dev->T("No block"))); + rightDisasm_->Add(new TextView(dev->T("No block"))); + blockStats_->SetText(""); + return; + } + + JitBlockDebugInfo debugInfo = blockCacheDebug->GetBlockDebugInfo(currentBlock_); + + snprintf(temp, sizeof(temp), "%08x", debugInfo.originalAddress); + blockAddr_->SetText(temp); + + // Alright. First generate the MIPS disassembly. + + // TODO: Need a way to communicate branch continuing. + for (const auto &line : debugInfo.origDisasm) { + leftDisasm_->Add(new TextView(line))->SetFocusable(true); + } + + // TODO : When we have both target and IR, need a third column. + if (debugInfo.targetDisasm.size()) { + for (const auto &line : debugInfo.targetDisasm) { + rightDisasm_->Add(new TextView(line))->SetFocusable(true); + } + } else { + for (const auto &line : debugInfo.irDisasm) { + rightDisasm_->Add(new TextView(line))->SetFocusable(true); + } + } + + int numMips = leftDisasm_->GetNumSubviews(); + int numHost = rightDisasm_->GetNumSubviews(); + + snprintf(temp, sizeof(temp), "%d to %d : %d%%", numMips, numHost, 100 * numHost / numMips); + blockStats_->SetText(temp); +} + +UI::EventReturn JitCompareScreen::OnAddressChange(UI::EventParams &e) { + std::lock_guard guard(MIPSComp::jitLock); + if (!MIPSComp::jit) { + return UI::EVENT_DONE; + } + JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); + if (!blockCache) + return UI::EVENT_DONE; + u32 addr; + if (blockAddr_->GetText().size() > 8) + return UI::EVENT_DONE; + if (1 == sscanf(blockAddr_->GetText().c_str(), "%08x", &addr)) { + if (Memory::IsValidAddress(addr)) { + currentBlock_ = blockCache->GetBlockNumberFromStartAddress(addr); + UpdateDisasm(); + } + } + return UI::EVENT_DONE; +} + +UI::EventReturn JitCompareScreen::OnShowStats(UI::EventParams &e) { + std::lock_guard guard(MIPSComp::jitLock); + if (!MIPSComp::jit) { + return UI::EVENT_DONE; + } + + JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); + if (!blockCache) + return UI::EVENT_DONE; + + BlockCacheStats bcStats; + blockCache->ComputeStats(bcStats); + NOTICE_LOG(JIT, "Num blocks: %i", bcStats.numBlocks); + NOTICE_LOG(JIT, "Average Bloat: %0.2f%%", 100 * bcStats.avgBloat); + NOTICE_LOG(JIT, "Min Bloat: %0.2f%% (%08x)", 100 * bcStats.minBloat, bcStats.minBloatBlock); + NOTICE_LOG(JIT, "Max Bloat: %0.2f%% (%08x)", 100 * bcStats.maxBloat, bcStats.maxBloatBlock); + + int ctr = 0, sz = (int)bcStats.bloatMap.size(); + for (auto iter : bcStats.bloatMap) { + if (ctr < 10 || ctr > sz - 10) { + NOTICE_LOG(JIT, "%08x: %f", iter.second, iter.first); + } else if (ctr == 10) { + NOTICE_LOG(JIT, "..."); + } + ctr++; + } + return UI::EVENT_DONE; +} + + +UI::EventReturn JitCompareScreen::OnSelectBlock(UI::EventParams &e) { + auto dev = GetI18NCategory(I18NCat::DEVELOPER); + + auto addressPrompt = new AddressPromptScreen(dev->T("Block address")); + addressPrompt->OnChoice.Handle(this, &JitCompareScreen::OnBlockAddress); + screenManager()->push(addressPrompt); + return UI::EVENT_DONE; +} + +UI::EventReturn JitCompareScreen::OnPrevBlock(UI::EventParams &e) { + currentBlock_--; + UpdateDisasm(); + return UI::EVENT_DONE; +} + +UI::EventReturn JitCompareScreen::OnNextBlock(UI::EventParams &e) { + currentBlock_++; + UpdateDisasm(); + return UI::EVENT_DONE; +} + +UI::EventReturn JitCompareScreen::OnBlockAddress(UI::EventParams &e) { + std::lock_guard guard(MIPSComp::jitLock); + if (!MIPSComp::jit) { + return UI::EVENT_DONE; + } + + JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); + if (!blockCache) + return UI::EVENT_DONE; + + if (Memory::IsValidAddress(e.a)) { + currentBlock_ = blockCache->GetBlockNumberFromStartAddress(e.a); + } else { + currentBlock_ = -1; + } + UpdateDisasm(); + return UI::EVENT_DONE; +} + +UI::EventReturn JitCompareScreen::OnRandomBlock(UI::EventParams &e) { + std::lock_guard guard(MIPSComp::jitLock); + if (!MIPSComp::jit) { + return UI::EVENT_DONE; + } + + JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); + if (!blockCache) + return UI::EVENT_DONE; + + int numBlocks = blockCache->GetNumBlocks(); + if (numBlocks > 0) { + int tries = 100; + while (tries-- > 0) { + currentBlock_ = rand() % numBlocks; + if (blockCache->IsValidBlock(currentBlock_)) { + break; + } + } + } + UpdateDisasm(); + return UI::EVENT_DONE; +} + +UI::EventReturn JitCompareScreen::OnRandomVFPUBlock(UI::EventParams &e) { + OnRandomBlock(IS_VFPU); + return UI::EVENT_DONE; +} + +UI::EventReturn JitCompareScreen::OnRandomFPUBlock(UI::EventParams &e) { + OnRandomBlock(IS_FPU); + return UI::EVENT_DONE; +} + +void JitCompareScreen::OnRandomBlock(int flag) { + std::lock_guard guard(MIPSComp::jitLock); + if (!MIPSComp::jit) { + return; + } + JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); + if (!blockCache) + return; + + int numBlocks = blockCache->GetNumBlocks(); + if (numBlocks > 0) { + bool anyWanted = false; + int tries = 0; + while (!anyWanted && tries < numBlocks) { + currentBlock_ = rand() % numBlocks; + if (blockCache->IsValidBlock(currentBlock_)) { + JitBlockDebugInfo b = blockCache->GetBlockDebugInfo(currentBlock_); + u32 mipsBytes = (u32)b.origDisasm.size() * 4; + for (u32 addr = b.originalAddress; addr < b.originalAddress + mipsBytes; addr += 4) { + MIPSOpcode opcode = Memory::Read_Instruction(addr); + if (MIPSGetInfo(opcode) & flag) { + char temp[256]; + MIPSDisAsm(opcode, addr, temp, sizeof(temp)); + // INFO_LOG(HLE, "Stopping at random instruction: %08x %s", addr, temp); + anyWanted = true; + break; + } + } + } + tries++; + } + + if (!anyWanted) + currentBlock_ = -1; + } + UpdateDisasm(); +} + +UI::EventReturn JitCompareScreen::OnCurrentBlock(UI::EventParams &e) { + std::lock_guard guard(MIPSComp::jitLock); + if (!MIPSComp::jit) { + return UI::EVENT_DONE; + } + JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache(); + if (!blockCache) + return UI::EVENT_DONE; + currentBlock_ = blockCache->GetBlockNumberFromAddress(currentMIPS->pc); + UpdateDisasm(); + return UI::EVENT_DONE; +} + + +void AddressPromptScreen::CreatePopupContents(UI::ViewGroup *parent) { + using namespace UI; + + auto dev = GetI18NCategory(I18NCat::DEVELOPER); + + addrView_ = new TextView(dev->T("Enter address"), ALIGN_HCENTER, false); + parent->Add(addrView_); + + ViewGroup *grid = new GridLayout(GridLayoutSettings(60, 40)); + parent->Add(grid); + + for (int i = 0; i < 16; ++i) { + char temp[16]; + snprintf(temp, 16, " %X ", i); + buttons_[i] = new Button(temp); + grid->Add(buttons_[i])->OnClick.Handle(this, &AddressPromptScreen::OnDigitButton); + } + + parent->Add(new Button(dev->T("Backspace")))->OnClick.Handle(this, &AddressPromptScreen::OnBackspace); +} + +void AddressPromptScreen::OnCompleted(DialogResult result) { + if (result == DR_OK) { + UI::EventParams e{}; + e.v = root_; + e.a = addr_; + OnChoice.Trigger(e); + } +} + +UI::EventReturn AddressPromptScreen::OnDigitButton(UI::EventParams &e) { + for (int i = 0; i < 16; ++i) { + if (buttons_[i] == e.v) { + AddDigit(i); + } + } + return UI::EVENT_DONE; +} + +UI::EventReturn AddressPromptScreen::OnBackspace(UI::EventParams &e) { + BackspaceDigit(); + return UI::EVENT_DONE; +} + +void AddressPromptScreen::AddDigit(int n) { + if ((addr_ & 0xF0000000) == 0) { + addr_ = addr_ * 16 + n; + } + UpdatePreviewDigits(); +} + +void AddressPromptScreen::BackspaceDigit() { + addr_ /= 16; + UpdatePreviewDigits(); +} + +void AddressPromptScreen::UpdatePreviewDigits() { + if (addr_ != 0) { + char temp[32]; + snprintf(temp, 32, "%8X", addr_); + addrView_->SetText(temp); + } else { + auto dev = GetI18NCategory(I18NCat::DEVELOPER); + addrView_->SetText(dev->T("Enter address")); + } +} + +bool AddressPromptScreen::key(const KeyInput &key) { + if (key.flags & KEY_DOWN) { + if (key.keyCode >= NKCODE_0 && key.keyCode <= NKCODE_9) { + AddDigit(key.keyCode - NKCODE_0); + } else if (key.keyCode >= NKCODE_A && key.keyCode <= NKCODE_F) { + AddDigit(10 + key.keyCode - NKCODE_A); + // NKCODE_DEL is backspace. + } else if (key.keyCode == NKCODE_DEL) { + BackspaceDigit(); + } else if (key.keyCode == NKCODE_ENTER) { + TriggerFinish(DR_OK); + } else { + return UIDialogScreen::key(key); + } + } else { + return UIDialogScreen::key(key); + } + return true; +} diff --git a/UI/JitCompareScreen.h b/UI/JitCompareScreen.h new file mode 100644 index 0000000000..027f3e7bb6 --- /dev/null +++ b/UI/JitCompareScreen.h @@ -0,0 +1,60 @@ +#pragma once +#include "Common/UI/UIScreen.h" +#include "UI/MiscScreens.h" + +class JitCompareScreen : public UIDialogScreenWithBackground { +public: + void CreateViews() override; + + const char *tag() const override { return "JitCompare"; } + +private: + void UpdateDisasm(); + UI::EventReturn OnRandomBlock(UI::EventParams &e); + UI::EventReturn OnRandomFPUBlock(UI::EventParams &e); + UI::EventReturn OnRandomVFPUBlock(UI::EventParams &e); + void OnRandomBlock(int flag); + + UI::EventReturn OnCurrentBlock(UI::EventParams &e); + UI::EventReturn OnSelectBlock(UI::EventParams &e); + UI::EventReturn OnPrevBlock(UI::EventParams &e); + UI::EventReturn OnNextBlock(UI::EventParams &e); + UI::EventReturn OnBlockAddress(UI::EventParams &e); + UI::EventReturn OnAddressChange(UI::EventParams &e); + UI::EventReturn OnShowStats(UI::EventParams &e); + + int currentBlock_ = -1; + + UI::TextView *blockName_; + UI::TextEdit *blockAddr_; + UI::TextView *blockStats_; + + UI::LinearLayout *leftDisasm_; + UI::LinearLayout *rightDisasm_; +}; + +class AddressPromptScreen : public PopupScreen { +public: + AddressPromptScreen(std::string_view title) : PopupScreen(title, "OK", "Cancel") {} + + const char *tag() const override { return "AddressPrompt"; } + + bool key(const KeyInput &key) override; + + UI::Event OnChoice; + +protected: + void CreatePopupContents(UI::ViewGroup *parent) override; + void OnCompleted(DialogResult result) override; + UI::EventReturn OnDigitButton(UI::EventParams &e); + UI::EventReturn OnBackspace(UI::EventParams &e); + +private: + void AddDigit(int n); + void BackspaceDigit(); + void UpdatePreviewDigits(); + + UI::TextView *addrView_ = nullptr; + UI::Button *buttons_[16]{}; + unsigned int addr_ = 0; +}; diff --git a/UI/UI.vcxproj b/UI/UI.vcxproj index 74aefd02e6..e1fcc93938 100644 --- a/UI/UI.vcxproj +++ b/UI/UI.vcxproj @@ -51,6 +51,7 @@ + @@ -90,6 +91,7 @@ + diff --git a/UI/UI.vcxproj.filters b/UI/UI.vcxproj.filters index 24c3cc6cf0..ba5da5148c 100644 --- a/UI/UI.vcxproj.filters +++ b/UI/UI.vcxproj.filters @@ -95,6 +95,9 @@ Screens + + Screens + @@ -190,6 +193,9 @@ Screens + + Screens + diff --git a/UWP/UI_UWP/UI_UWP.vcxproj b/UWP/UI_UWP/UI_UWP.vcxproj index f3b4c5a085..40838af5ed 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj +++ b/UWP/UI_UWP/UI_UWP.vcxproj @@ -127,6 +127,7 @@ + @@ -166,6 +167,7 @@ + diff --git a/UWP/UI_UWP/UI_UWP.vcxproj.filters b/UWP/UI_UWP/UI_UWP.vcxproj.filters index 18fe8834c3..b7bb978d11 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj.filters +++ b/UWP/UI_UWP/UI_UWP.vcxproj.filters @@ -38,6 +38,7 @@ + @@ -77,5 +78,6 @@ + \ No newline at end of file diff --git a/android/jni/Android.mk b/android/jni/Android.mk index c49ac79c4e..150161553f 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -855,6 +855,7 @@ LOCAL_SRC_FILES := \ $(SRC)/UI/TouchControlVisibilityScreen.cpp \ $(SRC)/UI/CwCheatScreen.cpp \ $(SRC)/UI/InstallZipScreen.cpp \ + $(SRC)/UI/JitCompareScreen.cpp \ $(SRC)/UI/OnScreenDisplay.cpp \ $(SRC)/UI/ProfilerDraw.cpp \ $(SRC)/UI/NativeApp.cpp \