dolphin/Source/Core/Common/Debug/CodeTrace.h

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;
};