From cdeac05e88120067a88114bbda03bbf4a8ecfa13 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 14 Jan 2015 16:57:19 +0300 Subject: [PATCH] vm::cast --- Utilities/StrFmt.h | 5 +- rpcs3/Emu/Memory/vm.h | 50 ++++++++++++++++++ rpcs3/Emu/Memory/vm_ptr.h | 60 +++++++++++----------- rpcs3/Emu/SysCalls/CB_FUNC.h | 5 +- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 14 ++--- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/cellFs.cpp | 4 +- 7 files changed, 99 insertions(+), 41 deletions(-) diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index c89f08e1d9..8e9c2bfb5a 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -656,9 +656,12 @@ namespace fmt enum of any appropriate type in this list External specializations (can be found in another headers): - vm::ps3::ptr (vm_ptr.h) (of appropriate address type, writing .addr() for printing can be avoided) + vm::ps3::ptr (vm_ptr.h) (with appropriate address type, using .addr() can be avoided) vm::ps3::bptr (vm_ptr.h) vm::psv::ptr (vm_ptr.h) + vm::ps3::ref (vm_ref.h) + vm::ps3::bref (vm_ref.h) + vm::psv::ref (vm_ref.h) Supported formatting: %d - decimal; only basic std::to_string() functionality diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index d548cda8fa..317dbc0a81 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -40,6 +40,56 @@ namespace vm return *get_ptr(addr); } + template + struct cast_ptr + { + static_assert(std::is_same::value, "Unsupported vm::cast() type"); + + __forceinline static u32 cast(const T& addr, const char* func) + { + return 0; + } + }; + + template<> + struct cast_ptr + { + __forceinline static u32 cast(const u32 addr, const char* func) + { + return addr; + } + }; + + template<> + struct cast_ptr + { + __forceinline static u32 cast(const u64 addr, const char* func) + { + const u32 res = (u32)addr; + if (res != addr) + { + throw fmt::Format("%s(): invalid address 0x%llx", func, addr); + } + + return res; + } + }; + + template + struct cast_ptr> + { + __forceinline static u32 cast(const be_t& addr, const char* func) + { + return cast_ptr::cast(addr.value(), func); + } + }; + + template + __forceinline static u32 cast(const T& addr, const char* func = "vm::cast") + { + return cast_ptr::cast(addr, func); + } + namespace ps3 { void init(); diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index 8433588d79..122753b0ee 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -11,49 +11,50 @@ namespace vm public: typedef typename std::remove_cv::type type; + static const u32 address_size = (u32)sizeof(AT); _ptr_base operator++ (int) { AT result = m_addr; - m_addr += sizeof(AT); + m_addr += address_size; return make(result); } _ptr_base& operator++ () { - m_addr += sizeof(AT); + m_addr += address_size; return *this; } _ptr_base operator-- (int) { AT result = m_addr; - m_addr -= sizeof(AT); + m_addr -= address_size; return make(result); } _ptr_base& operator-- () { - m_addr -= sizeof(AT); + m_addr -= address_size; return *this; } _ptr_base& operator += (AT count) { - m_addr += count * sizeof(AT); + m_addr += count * address_size; return *this; } _ptr_base& operator -= (AT count) { - m_addr -= count * sizeof(AT); + m_addr -= count * address_size; return *this; } - _ptr_base operator + (typename remove_be_t::type count) const { return make(m_addr + count * sizeof(AT)); } - _ptr_base operator + (typename to_be_t::type count) const { return make(m_addr + count * sizeof(AT)); } - _ptr_base operator - (typename remove_be_t::type count) const { return make(m_addr - count * sizeof(AT)); } - _ptr_base operator - (typename to_be_t::type count) const { return make(m_addr - count * sizeof(AT)); } + _ptr_base operator + (typename remove_be_t::type count) const { return make(m_addr + count * address_size); } + _ptr_base operator + (typename to_be_t::type count) const { return make(m_addr + count * address_size); } + _ptr_base operator - (typename remove_be_t::type count) const { return make(m_addr - count * address_size); } + _ptr_base operator - (typename to_be_t::type count) const { return make(m_addr - count * address_size); } __forceinline bool operator <(const _ptr_base& right) const { return m_addr < right.m_addr; } __forceinline bool operator <=(const _ptr_base& right) const { return m_addr <= right.m_addr; } @@ -67,12 +68,12 @@ namespace vm __forceinline _ptr_base::value, typename to_be_t::type, AT>>& operator *() const { - return vm::get_ref<_ptr_base::value, typename to_be_t::type, AT>>>((u32)m_addr); + return vm::get_ref<_ptr_base::value, typename to_be_t::type, AT>>>(vm::cast(m_addr)); } __forceinline _ptr_base::value, typename to_be_t::type, AT>>& operator [](AT index) const { - return vm::get_ref<_ptr_base::value, typename to_be_t::type, AT>>>((u32)(m_addr + sizeof(AT)* index)); + return vm::get_ref<_ptr_base::value, typename to_be_t::type, AT>>>(vm::cast(m_addr + sizeof(AT)* index)); } //typedef typename invert_be_t::type AT2; @@ -109,68 +110,69 @@ namespace vm public: typedef typename std::remove_cv::type type; + static const u32 data_size = (u32)sizeof(T); __forceinline T* const operator -> () const { - return vm::get_ptr((u32)m_addr); + return vm::get_ptr(vm::cast(m_addr)); } _ptr_base operator++ (int) { AT result = m_addr; - m_addr += sizeof(T); + m_addr += data_size; return make(result); } _ptr_base& operator++ () { - m_addr += sizeof(T); + m_addr += data_size; return *this; } _ptr_base operator-- (int) { AT result = m_addr; - m_addr -= sizeof(T); + m_addr -= data_size; return make(result); } _ptr_base& operator-- () { - m_addr -= sizeof(T); + m_addr -= data_size; return *this; } _ptr_base& operator += (AT count) { - m_addr += count * sizeof(T); + m_addr += count * data_size; return *this; } _ptr_base& operator -= (AT count) { - m_addr -= count * sizeof(T); + m_addr -= count * data_size; return *this; } - _ptr_base operator + (typename remove_be_t::type count) const { return make(m_addr + count * sizeof(T)); } - _ptr_base operator + (typename to_be_t::type count) const { return make(m_addr + count * sizeof(T)); } - _ptr_base operator - (typename remove_be_t::type count) const { return make(m_addr - count * sizeof(T)); } - _ptr_base operator - (typename to_be_t::type count) const { return make(m_addr - count * sizeof(T)); } + _ptr_base operator + (typename remove_be_t::type count) const { return make(m_addr + count * data_size); } + _ptr_base operator + (typename to_be_t::type count) const { return make(m_addr + count * data_size); } + _ptr_base operator - (typename remove_be_t::type count) const { return make(m_addr - count * data_size); } + _ptr_base operator - (typename to_be_t::type count) const { return make(m_addr - count * data_size); } __forceinline T& operator *() const { - return vm::get_ref((u32)m_addr); + return vm::get_ref(vm::cast(m_addr)); } __forceinline T& operator [](typename remove_be_t::type index) const { - return vm::get_ref((u32)(m_addr + sizeof(T) * index)); + return vm::get_ref(vm::cast(m_addr + data_size * index)); } __forceinline T& operator [](typename to_be_t::forced_type index) const { - return vm::get_ref((u32)(m_addr + sizeof(T)* index)); + return vm::get_ref(vm::cast(m_addr + data_size * index)); } __forceinline bool operator <(const _ptr_base& right) const { return m_addr < right.m_addr; } @@ -224,7 +226,7 @@ namespace vm T* get_ptr() const { - return vm::get_ptr((u32)m_addr); + return vm::get_ptr(vm::cast(m_addr)); } static _ptr_base make(AT addr) @@ -253,7 +255,7 @@ namespace vm void* get_ptr() const { - return vm::get_ptr((u32)m_addr); + return vm::get_ptr(vm::cast(m_addr)); } explicit operator void*() const @@ -313,7 +315,7 @@ namespace vm const void* get_ptr() const { - return vm::get_ptr((u32)m_addr); + return vm::get_ptr(vm::cast(m_addr)); } explicit operator const void*() const diff --git a/rpcs3/Emu/SysCalls/CB_FUNC.h b/rpcs3/Emu/SysCalls/CB_FUNC.h index 78b82961dc..129fd5c109 100644 --- a/rpcs3/Emu/SysCalls/CB_FUNC.h +++ b/rpcs3/Emu/SysCalls/CB_FUNC.h @@ -165,8 +165,9 @@ namespace vm template __forceinline RT _ptr_base::operator()(CPUThread& CPU, T... args) const { - const u32 pc = vm::get_ref>((u32)m_addr); - const u32 rtoc = vm::get_ref>((u32)m_addr + 4); + auto data = vm::get_ptr>(vm::cast(m_addr)); + const u32 pc = data[0]; + const u32 rtoc = data[1]; assert(CPU.GetType() == CPU_THREAD_PPU); return cb_detail::_func_caller::call(static_cast(CPU), pc, rtoc, args...); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index fa043029ef..3148cf5c3d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -1347,9 +1347,10 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm: } } - s32 depth = (u32)queue->m_depth; - s32 size = (u32)queue->m_size; - memcpy(vm::get_ptr((u64)(queue->m_buffer.addr() & ~1ull) + size * (position >= depth ? position - depth : position)), buffer.get_ptr(), size); + const s32 depth = (u32)queue->m_depth; + const s32 size = (u32)queue->m_size; + const u32 addr = vm::cast((queue->m_buffer.addr() & ~1ull) + size * (position >= depth ? position - depth : position)); + memcpy(vm::get_ptr(addr), buffer.get_ptr(), size); s32 res; if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) @@ -1722,9 +1723,10 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: } } - s32 depth = (u32)queue->m_depth; - s32 size = (u32)queue->m_size; - memcpy(buffer.get_ptr(), vm::get_ptr((u64)(queue->m_buffer.addr() & ~1ull) + size * (position >= depth ? position - depth : position)), size); + const s32 depth = (u32)queue->m_depth; + const s32 size = (u32)queue->m_size; + const u32 addr = vm::cast((queue->m_buffer.addr() & ~1) + size * (position >= depth ? position - depth : position)); + memcpy(buffer.get_ptr(), vm::get_ptr(addr), size); s32 res; if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 906234387c..8ad6d0c650 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -310,7 +310,7 @@ struct sys_callback void sysutilSendSystemCommand(u64 status, u64 param) { - // TODO: check it and find the source of the return value (not sure that void becomes CELL_OK) + // TODO: check it and find the source of the return value (void isn't equal to CELL_OK) for (auto& cb : g_sys_callback) { if (cb.func) diff --git a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp index a6a2c04be4..3fb8bf1db7 100644 --- a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp @@ -945,7 +945,7 @@ void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptr aio, vm::ref id, vm::ptr xaio, int error, int xid, u64 size)> func) +int cellFsAioRead(vm::ptr aio, vm::ptr id, vm::ptr xaio, int error, int xid, u64 size)> func) { sys_fs->Warning("cellFsAioRead(aio=0x%x, id=0x%x, func=0x%x)", aio, id, func); @@ -964,7 +964,7 @@ int cellFsAioRead(vm::ptr aio, vm::ref id, vm::ptr