83 lines
2.1 KiB
C++
83 lines
2.1 KiB
C++
// Copyright 2022 Dolphin Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#include <optional>
|
|
#include <set>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "Common/CommonTypes.h"
|
|
|
|
namespace Core
|
|
{
|
|
class CPUThreadGuard;
|
|
}
|
|
|
|
struct InstructionAttributes
|
|
{
|
|
u32 address = 0;
|
|
std::string instruction = "";
|
|
std::string reg0 = "";
|
|
std::string reg1 = "";
|
|
std::string reg2 = "";
|
|
std::string reg3 = "";
|
|
std::optional<u32> memory_target = std::nullopt;
|
|
u32 memory_target_size = 4;
|
|
bool is_store = false;
|
|
bool is_load = false;
|
|
};
|
|
|
|
struct TraceOutput
|
|
{
|
|
u32 address = 0;
|
|
std::optional<u32> memory_target = std::nullopt;
|
|
std::string instruction;
|
|
};
|
|
|
|
struct AutoStepResults
|
|
{
|
|
std::vector<std::string> reg_tracked;
|
|
std::set<u32> mem_tracked;
|
|
u32 count = 0;
|
|
bool timed_out = false;
|
|
bool trackers_empty = false;
|
|
};
|
|
|
|
enum class HitType : u32
|
|
{
|
|
SKIP = (1 << 0), // Not a hit
|
|
OVERWRITE = (1 << 1), // Tracked value gets overwritten by untracked. Typically skipped.
|
|
MOVED = (1 << 2), // Target duplicated to another register, unchanged.
|
|
SAVELOAD = (1 << 3), // Target saved or loaded. Priority over Pointer.
|
|
POINTER = (1 << 4), // Target used as pointer/offset for save or load
|
|
PASSIVE = (1 << 5), // Conditional, etc, but not pointer. Unchanged
|
|
ACTIVE = (1 << 6), // Math, etc. Changed.
|
|
UPDATED = (1 << 7), // Masked or math without changing register.
|
|
};
|
|
|
|
class CodeTrace
|
|
{
|
|
public:
|
|
enum class AutoStop
|
|
{
|
|
Always,
|
|
Used,
|
|
Changed
|
|
};
|
|
|
|
void SetRegTracked(const std::string& reg);
|
|
AutoStepResults AutoStepping(const Core::CPUThreadGuard& guard, bool continue_previous = false,
|
|
AutoStop stop_on = AutoStop::Always);
|
|
|
|
private:
|
|
InstructionAttributes GetInstructionAttributes(const TraceOutput& line) const;
|
|
TraceOutput SaveCurrentInstruction(const Core::CPUThreadGuard* guard) const;
|
|
HitType TraceLogic(const TraceOutput& current_instr, bool first_hit = false);
|
|
|
|
bool m_recording = false;
|
|
std::vector<std::string> m_reg_autotrack;
|
|
std::set<u32> m_mem_autotrack;
|
|
};
|