#include "VuInstruction.h" #include "common/util/Assert.h" #include "fmt/core.h" namespace decompiler { VuInstructionAtom VuInstructionAtom::make_vf(int idx) { ASSERT(idx >= 0 && idx <= 31); return {Kind::VF, idx}; } VuInstructionAtom VuInstructionAtom::make_vi(int idx) { ASSERT(idx >= 0 && idx <= 15); return {Kind::VI, idx}; } VuInstructionAtom VuInstructionAtom::make_label(int idx) { return {Kind::LABEL, idx}; } VuInstructionAtom VuInstructionAtom::make_q() { return {Kind::Q}; } VuInstructionAtom VuInstructionAtom::make_acc() { return {Kind::ACC}; } VuInstructionAtom VuInstructionAtom::make_imm(u64 value) { return {Kind::IMM, (s64)value}; } VuInstructionAtom VuInstructionAtom::make_load_store_imm(s64 value) { return {Kind::LOAD_STORE_IMM, value}; } VuInstructionAtom VuInstructionAtom::make_i() { return {Kind::I}; } VuInstructionAtom VuInstructionAtom::make_p() { return {Kind::P}; } VuInstructionAtom VuInstructionAtom::make_r() { return {Kind::R}; } bool VuInstructionAtom::is_int_reg(int idx) const { return m_kind == Kind::VI && m_value == idx; } std::string VuInstructionAtom::to_string(const std::vector& labels) const { switch (m_kind) { case Kind::VF: return fmt::format("vf{:02d}", m_value); case Kind::Q: return "Q"; case Kind::ACC: return "ACC"; case Kind::IMM: if (m_value < 0) { return fmt::format("-0x{:x}", -m_value); } else { return fmt::format("0x{:x}", m_value); } case Kind::I: return "I"; case Kind::P: return "P"; case Kind::R: return "R"; case Kind::LABEL: if (m_value < (int)labels.size()) { return labels.at(m_value); } else { return "BAD-LABEL"; } case Kind::LOAD_STORE_IMM: return fmt::format("{}", m_value); case Kind::VI: return fmt::format("vi{:02d}", m_value); case Kind::INVALID: default: ASSERT(false); } } VuInstruction VuInstruction::make_fp_constant(u32 value) { VuInstruction result; memcpy(&result.fp, &value, sizeof(float)); result.kind = VuInstrK::FP_CONSTANT; return result; } } // namespace decompiler