From 474ca1b008cce750c5b7657af87cb3480af05e2f Mon Sep 17 00:00:00 2001 From: spectranator Date: Tue, 21 May 2024 13:40:10 +0200 Subject: [PATCH] Implemented basic IR serialization --- .../frontend/A64/translate/a64_translate.cpp | 3 +++ .../dynarmic/src/dynarmic/ir/basic_block.cpp | 5 +++++ .../dynarmic/src/dynarmic/ir/basic_block.h | 3 +++ .../src/dynarmic/ir/microinstruction.cpp | 7 +++++++ .../src/dynarmic/ir/microinstruction.h | 2 ++ externals/dynarmic/src/dynarmic/ir/value.cpp | 18 ++++++++++++++++++ externals/dynarmic/src/dynarmic/ir/value.h | 4 ++++ 7 files changed, 42 insertions(+) diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp index 05996aeb6..7f9632347 100644 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp @@ -43,6 +43,9 @@ IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory ASSERT_MSG(block.HasTerminal(), "Terminal has not been set"); + std::vector fres; + block.Serialize(fres); + block.SetEndLocation(*visitor.ir.current_location); return block; diff --git a/externals/dynarmic/src/dynarmic/ir/basic_block.cpp b/externals/dynarmic/src/dynarmic/ir/basic_block.cpp index cc7eb48ef..b1253b11b 100644 --- a/externals/dynarmic/src/dynarmic/ir/basic_block.cpp +++ b/externals/dynarmic/src/dynarmic/ir/basic_block.cpp @@ -120,6 +120,11 @@ const size_t& Block::CycleCount() const { return cycle_count; } +void Block::Serialize(std::vector& fres) const { + for (const auto& inst : *this) + inst.Serialize(*this, fres); +} + static std::string TerminalToString(const Terminal& terminal_variant) { struct : boost::static_visitor { std::string operator()(const Term::Invalid&) const { diff --git a/externals/dynarmic/src/dynarmic/ir/basic_block.h b/externals/dynarmic/src/dynarmic/ir/basic_block.h index 18d7fadae..e01d4ca56 100644 --- a/externals/dynarmic/src/dynarmic/ir/basic_block.h +++ b/externals/dynarmic/src/dynarmic/ir/basic_block.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -139,6 +140,8 @@ public: /// Gets an immutable reference to the cycle count for this basic block. const size_t& CycleCount() const; + void Serialize(std::vector&) const; + private: /// Description of the starting location of this block LocationDescriptor location; diff --git a/externals/dynarmic/src/dynarmic/ir/microinstruction.cpp b/externals/dynarmic/src/dynarmic/ir/microinstruction.cpp index 50af036dd..ca16fbeff 100644 --- a/externals/dynarmic/src/dynarmic/ir/microinstruction.cpp +++ b/externals/dynarmic/src/dynarmic/ir/microinstruction.cpp @@ -652,6 +652,13 @@ void Inst::SetArg(size_t index, Value value) { args[index] = value; } +void Inst::Serialize(const Block& block, std::vector& fres) const { + fres.push_back(static_cast(GetOpcode())); + fres.push_back(NumArgs()); + for (unsigned idx = 0; idx != NumArgs(); idx++) + GetArg(idx).Serialize(block, fres); +} + void Inst::Invalidate() { ClearArgs(); op = Opcode::Void; diff --git a/externals/dynarmic/src/dynarmic/ir/microinstruction.h b/externals/dynarmic/src/dynarmic/ir/microinstruction.h index 26b6b899f..0e59247f0 100644 --- a/externals/dynarmic/src/dynarmic/ir/microinstruction.h +++ b/externals/dynarmic/src/dynarmic/ir/microinstruction.h @@ -136,6 +136,8 @@ public: Value GetArg(size_t index) const; void SetArg(size_t index, Value value); + void Serialize(const Block&, std::vector&) const; + void Invalidate(); void ClearArgs(); diff --git a/externals/dynarmic/src/dynarmic/ir/value.cpp b/externals/dynarmic/src/dynarmic/ir/value.cpp index 20f94cb5f..b3699d969 100644 --- a/externals/dynarmic/src/dynarmic/ir/value.cpp +++ b/externals/dynarmic/src/dynarmic/ir/value.cpp @@ -197,6 +197,24 @@ AccType Value::GetAccType() const { return inner.imm_acctype; } +void Value::Serialize(const Block& block, std::vector& fres) const { + fres.push_back(static_cast(type)); + if (type != Type::Opaque) { + for (unsigned it = 0; it != sizeof(inner.raw)/sizeof(*inner.raw); it++) + fres.push_back(inner.raw[it]); + } else { + unsigned it = 0; + for (const auto& instr : block) { + if (&instr == inner.inst) { + fres.push_back(it); + return; + } + ++it; + } + ASSERT_MSG(false, "Instruction index not found"); + } +} + s64 Value::GetImmediateAsS64() const { ASSERT(IsImmediate()); diff --git a/externals/dynarmic/src/dynarmic/ir/value.h b/externals/dynarmic/src/dynarmic/ir/value.h index 8f70110a8..a1a2e5f2a 100644 --- a/externals/dynarmic/src/dynarmic/ir/value.h +++ b/externals/dynarmic/src/dynarmic/ir/value.h @@ -26,6 +26,7 @@ enum class Vec; namespace Dynarmic::IR { class Inst; +class Block; enum class AccType; enum class Cond; @@ -75,6 +76,8 @@ public: Cond GetCond() const; AccType GetAccType() const; + void Serialize(const Block&, std::vector&) const; + /** * Retrieves the immediate of a Value instance as a signed 64-bit value. * @@ -147,6 +150,7 @@ private: CoprocessorInfo imm_coproc; Cond imm_cond; AccType imm_acctype; + uint16_t raw[4]; } inner; }; static_assert(sizeof(Value) <= 2 * sizeof(u64), "IR::Value should be kept small in size");