diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 43542f5278..b73d036daf 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -583,7 +583,6 @@ - @@ -993,6 +992,7 @@ + true true @@ -1194,7 +1194,6 @@ - @@ -1408,6 +1407,7 @@ + true true diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 39c329f066..e00f5b24ba 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -123,6 +123,9 @@ MIPS + + MIPS + MIPS @@ -1315,9 +1318,6 @@ HLE\Libraries - - MIPS - @@ -1350,6 +1350,9 @@ MIPS + + MIPS + MIPS @@ -2109,9 +2112,6 @@ HLE\Libraries - - MIPS - diff --git a/Core/MIPS/MIPSTracer.cpp b/Core/MIPS/MIPSTracer.cpp new file mode 100644 index 0000000000..328e10645a --- /dev/null +++ b/Core/MIPS/MIPSTracer.cpp @@ -0,0 +1,41 @@ +// Copyright (c) 2024- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "Core/MIPS/MIPSTracer.h" + +#include // for std::memcpy +#include "Core/MIPS/MIPSTables.h" // for MIPSDisAsm + + +bool TraceBlockStorage::push_block(u32* instructions, u32 size) { + if (cur_offset + size >= raw_instructions.size()) { + return false; + } + std::memcpy(cur_data_ptr, instructions, size); + cur_offset += size; + cur_data_ptr += size; + return true; +} + +void TraceBlockStorage::initialize(u32 capacity) { + raw_instructions.resize(capacity); + cur_offset = 0; + cur_data_ptr = raw_instructions.data(); +} + + +MIPSTracer mipsTracer; diff --git a/Core/MIPS/MIPSTracer.h b/Core/MIPS/MIPSTracer.h new file mode 100644 index 0000000000..15706c1c66 --- /dev/null +++ b/Core/MIPS/MIPSTracer.h @@ -0,0 +1,138 @@ +// Copyright (c) 2024- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include +#include +#include +#include + +#include "Common/CommonTypes.h" +#include "Core/Opcode.h" + + + +struct TraceBlockInfo { + u32 virt_address; + u32 size; + u32 storage_index; +}; + +struct TraceBlockStorage { + std::vector raw_instructions; + u32 cur_offset; + u32* cur_data_ptr; + + TraceBlockStorage(u32 capacity): + raw_instructions(capacity, 0), + cur_offset(0), + cur_data_ptr(raw_instructions.data()) + {} + + TraceBlockStorage(): raw_instructions(), cur_offset(0), cur_data_ptr(nullptr) {} + + bool push_block(u32* instructions, u32 size); + + void initialize(u32 capacity); + + Memory::Opcode operator[](u32 index) { + return Memory::Opcode(raw_instructions[index]); + } +}; + + +template +struct CyclicBuffer { + std::vector buffer; + u32 current_index; + bool overflow; + + explicit CyclicBuffer(u32 capacity) : buffer(capacity, T()), current_index(0), overflow(false) {} + + CyclicBuffer(): buffer(), current_index(0), overflow(false) {} + + void push_back(const T& value); + void push_back(T&& value); + + void clear(); + void resize(u32 new_capacity); + + std::vector get_content() const; +}; + +template +std::vector CyclicBuffer::get_content() const { + if (!overflow) { + return std::vector(buffer.begin(), buffer.begin() + current_index); + } + + std::vector ans; + ans.reserve(buffer.size()); + std::copy(buffer.begin() + current_index, buffer.end(), std::back_inserter(ans)); + std::copy(buffer.begin(), buffer.begin() + current_index, std::back_inserter(ans)); + return ans; +} + +template +void CyclicBuffer::push_back(const T& value) { + buffer[current_index] = value; + ++current_index; + if (current_index == buffer.size()) { + current_index = 0; + overflow = true; + } +} + +template +void CyclicBuffer::push_back(T&& value) { + buffer[current_index] = std::move(value); + ++current_index; + if (current_index == buffer.size()) { + current_index = 0; + overflow = true; + } +} + +template +void CyclicBuffer::clear() { + buffer.clear(); + current_index = 0; + overflow = false; +} + +template +void CyclicBuffer::resize(u32 new_capacity) { + buffer.resize(new_capacity); +} + +struct MIPSTracer { + std::vector trace_info; + + // The trace might be very big, in that case I don't mind losing the oldest entries. + CyclicBuffer executed_blocks; + + std::unordered_map hash_to_index; + + TraceBlockStorage storage; + + std::string logging_path; + + MIPSTracer(): trace_info(), executed_blocks(), hash_to_index(), storage(), logging_path() {} +}; + +extern MIPSTracer mipsTracer; diff --git a/Core/MIPSTracer.cpp b/Core/MIPSTracer.cpp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Core/MIPSTracer.h b/Core/MIPSTracer.h deleted file mode 100644 index 6f70f09bee..0000000000 --- a/Core/MIPSTracer.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once