#pragma once namespace vm { template class _ref_base { protected: AT m_addr; public: typedef T type; static_assert(!std::is_pointer::value, "vm::_ref_base<> error: invalid type (pointer)"); static_assert(!std::is_reference::value, "vm::_ref_base<> error: invalid type (reference)"); typedef typename remove_be_t::type le_type; typedef typename to_be_t::type be_type; operator T&() { return get_ref(m_addr); } operator const T&() const { return get_ref(m_addr); } AT addr() const { return m_addr; } static _ref_base make(const AT& addr) { return reinterpret_cast<_ref_base&>(addr); } _ref_base& operator = (le_type right) { get_ref(m_addr) = right; return *this; } const _ref_base& operator = (le_type right) const { get_ref(m_addr) = right; return *this; } _ref_base& operator = (be_type right) { get_ref(m_addr) = right; return *this; } const _ref_base& operator = (be_type right) const { get_ref(m_addr) = right; return *this; } }; //BE reference to LE data template using brefl = _ref_base::type>; //BE reference to BE data template using brefb = _ref_base::type, typename to_be_t::type>; //LE reference to BE data template using lrefb = _ref_base::type, AT>; //LE reference to LE data template using lrefl = _ref_base; namespace ps3 { //default reference for HLE functions (LE reference to BE data) template using ref = lrefb; //default reference for HLE structures (BE reference to BE data) template using bref = brefb; } namespace psv { //default reference for HLE functions & structures (LE reference to LE data) template using ref = lrefl; } //PS3 emulation is main now, so lets it be as default using namespace ps3; } namespace fmt { // external specialization for fmt::format function template struct unveil, false> { typedef typename unveil::result_type result_type; __forceinline static result_type get_value(const vm::_ref_base& arg) { return unveil::get_value(arg.addr()); } }; } // external specializations for PPU GPR (SC_FUNC.h, CB_FUNC.h) template struct cast_ppu_gpr; template struct cast_ppu_gpr, false> { __forceinline static u64 to_gpr(const vm::_ref_base& value) { return cast_ppu_gpr::value>::to_gpr(value.addr()); } __forceinline static vm::_ref_base from_gpr(const u64 reg) { return vm::_ref_base::make(cast_ppu_gpr::value>::from_gpr(reg)); } }; // external specializations for ARMv7 GPR template struct cast_armv7_gpr; template struct cast_armv7_gpr, false> { __forceinline static u32 to_gpr(const vm::_ref_base& value) { return cast_armv7_gpr::value>::to_gpr(value.addr()); } __forceinline static vm::_ref_base from_gpr(const u32 reg) { return vm::_ref_base::make(cast_armv7_gpr::value>::from_gpr(reg)); } };