Implemented basic IR serialization

This commit is contained in:
spectranator 2024-05-21 13:40:10 +02:00
parent b8acc0390a
commit 474ca1b008
7 changed files with 42 additions and 0 deletions

View file

@ -43,6 +43,9 @@ IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory
ASSERT_MSG(block.HasTerminal(), "Terminal has not been set");
std::vector<uint16_t> fres;
block.Serialize(fres);
block.SetEndLocation(*visitor.ir.current_location);
return block;

View file

@ -120,6 +120,11 @@ const size_t& Block::CycleCount() const {
return cycle_count;
}
void Block::Serialize(std::vector<uint16_t>& 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> {
std::string operator()(const Term::Invalid&) const {

View file

@ -8,6 +8,7 @@
#include <initializer_list>
#include <memory>
#include <optional>
#include <vector>
#include <string>
#include <mcl/container/intrusive_list.hpp>
@ -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<uint16_t>&) const;
private:
/// Description of the starting location of this block
LocationDescriptor location;

View file

@ -652,6 +652,13 @@ void Inst::SetArg(size_t index, Value value) {
args[index] = value;
}
void Inst::Serialize(const Block& block, std::vector<uint16_t>& fres) const {
fres.push_back(static_cast<uint16_t>(GetOpcode()));
fres.push_back(NumArgs());
for (unsigned idx = 0; idx != NumArgs(); idx++)
GetArg(idx).Serialize(block, fres);
}
void Inst::Invalidate() {
ClearArgs();
op = Opcode::Void;

View file

@ -136,6 +136,8 @@ public:
Value GetArg(size_t index) const;
void SetArg(size_t index, Value value);
void Serialize(const Block&, std::vector<uint16_t>&) const;
void Invalidate();
void ClearArgs();

View file

@ -197,6 +197,24 @@ AccType Value::GetAccType() const {
return inner.imm_acctype;
}
void Value::Serialize(const Block& block, std::vector<uint16_t>& fres) const {
fres.push_back(static_cast<uint16_t>(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());

View file

@ -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<uint16_t>&) 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");