From bd71c1200e1e12b8177fbb64b997c9c398fdd29d Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 7 Jan 2015 19:44:47 +0300 Subject: [PATCH] CB_FUNC/SC_FUNC fixed --- rpcs3/Emu/ARMv7/PSVFuncList.h | 1 + rpcs3/Emu/Cell/PPUThread.h | 87 ++++++++++++++++++++++++++++- rpcs3/Emu/Memory/vm.h | 5 ++ rpcs3/Emu/Memory/vm_var.h | 101 ++++++++++++++++------------------ rpcs3/Emu/SysCalls/CB_FUNC.h | 24 ++++---- rpcs3/Emu/SysCalls/SC_FUNC.h | 16 +++--- 6 files changed, 157 insertions(+), 77 deletions(-) diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.h b/rpcs3/Emu/ARMv7/PSVFuncList.h index 998225799d..5dda63c3db 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.h +++ b/rpcs3/Emu/ARMv7/PSVFuncList.h @@ -475,6 +475,7 @@ namespace psv_func_detail static __forceinline void func(ARMv7Thread& CPU, T result) { + CPU.GPR[0] = 0; // TODO (T&)CPU.GPR[0] = result; } }; diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 717dd151f1..c0d5eda43c 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -811,4 +811,89 @@ public: cpu_thread& args(std::initializer_list values) override; cpu_thread& run() override; ppu_thread& gpr(uint index, u64 value); -}; \ No newline at end of file +}; + +template +struct cast_ppu_gpr +{ + static_assert(sizeof(T) <= 8, "Type for cast_ppu_gpr is invalid (too big)"); + + static u64 func(const T& value) + { + u64 result = 0; + (T&)result = value; + return result; + } +}; + +template +struct cast_ppu_gpr +{ + static u64 func(const T& value) + { + return (u8&)value; + } +}; + +template +struct cast_ppu_gpr +{ + static u64 func(const T& value) + { + return (u16&)value; + } +}; + +template +struct cast_ppu_gpr +{ + static u64 func(const T& value) + { + return (u32&)value; + } +}; + +template +struct cast_ppu_gpr +{ + static u64 func(const T& value) + { + return (u64&)value; + } +}; + +template<> +struct cast_ppu_gpr +{ + static u64 func(const s8& value) + { + return value; + } +}; + +template<> +struct cast_ppu_gpr +{ + static u64 func(const s16& value) + { + return value; + } +}; + +template<> +struct cast_ppu_gpr +{ + static u64 func(const s32& value) + { + return value; + } +}; + +template<> +struct cast_ppu_gpr +{ + static u64 func(const s64& value) + { + return value; + } +}; diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index 1e6b64959c..d548cda8fa 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -1,6 +1,8 @@ #pragma once #include "Memory.h" +class CPUThread; + namespace vm { enum memory_location : uint @@ -171,6 +173,9 @@ namespace vm } void close(); + + u32 stack_push(CPUThread& CPU, u32 size, u32 align, u32& old_pos); + void stack_pop(CPUThread& CPU, u32 addr, u32 old_pos); } #include "vm_ref.h" diff --git a/rpcs3/Emu/Memory/vm_var.h b/rpcs3/Emu/Memory/vm_var.h index 1b59653d2d..0975a00913 100644 --- a/rpcs3/Emu/Memory/vm_var.h +++ b/rpcs3/Emu/Memory/vm_var.h @@ -1,9 +1,6 @@ #pragma once class CPUThread; -class PPUThread; -class SPUThread; -class ARMv7Thread; namespace vm { @@ -501,108 +498,102 @@ namespace vm } }; - u32 stack_push(CPUThread& CPU, u32 size, u32 align, u32& old_pos); - void stack_pop(CPUThread& CPU, u32 addr, u32 old_pos); - template class stackvar { - T* m_ptr; - u32 m_addr; - u32 m_size; - u32 m_align; - u32 m_old_pos; - CPUThread& m_thread; - - void alloc() + struct stack_allocation { - m_addr = stack_push(m_thread, m_size, m_align, m_old_pos); - m_ptr = vm::get_ptr(m_addr); - } + T* ptr; + u32 addr; + u32 size; + u32 align; + u32 old_pos; - void dealloc() - { - if (m_addr) + stack_allocation(CPUThread& CPU, u32 size, u32 align) + : size(size) + , align(align) { - stack_pop(m_thread, m_addr, m_old_pos); - m_addr = 0; - m_ptr = vm::get_ptr(0u); + addr = stack_push(CPU, size, align, old_pos); + ptr = vm::get_ptr(addr); } - } + + stack_allocation() = delete; + stack_allocation(const stack_allocation& r) = delete; + stack_allocation(stack_allocation&& r) = delete; + stack_allocation& operator = (const stack_allocation& r) = delete; + stack_allocation& operator = (stack_allocation&& r) = delete; + + } const m_data; + + CPUThread& m_thread; public: stackvar(CPUThread& CPU, u32 size = sizeof(T), u32 align = __alignof(T)) - : m_size(size) - , m_align(align) + : m_data(CPU, size, align) , m_thread(CPU) { - alloc(); } stackvar(const stackvar& r) - : m_size(r.m_size) - , m_align(r.m_align) + : m_data(r.m_thread, r.m_data.m_size, r.m_data.m_align) , m_thread(r.m_thread) { - alloc(); - *m_ptr = *r.m_ptr; + *m_data.ptr = *r.m_data.ptr; } - stackvar(stackvar&& r) - : m_ptr(r.m_ptr) - , m_addr(r.m_addr) - , m_size(r.m_size) - , m_align(r.m_align) - , m_old_pos(r.m_old_pos) - , m_thread(r.m_thread) - { - r.m_addr = 0; - r.m_ptr = vm::get_ptr(0u); - } + stackvar(stackvar&& r) = delete; ~stackvar() { - dealloc(); + stack_pop(m_thread, m_data.addr, m_data.old_pos); } + stackvar& operator = (const stackvar& r) + { + *m_data.ptr = *r.m_data.ptr; + return *this; + } + + stackvar& operator = (stackvar&& r) = delete; + T* operator -> () { - return m_ptr; + return m_data.ptr; } const T* operator -> () const { - return m_ptr; + return m_data.ptr; } T* get_ptr() { - return m_ptr; + return m_data.ptr; } const T* get_ptr() const { - return m_ptr; + return m_data.ptr; } T& value() { - return *m_ptr; + return *m_data.ptr; } const T& value() const { - return *m_ptr; + return *m_data.ptr; } u32 addr() const { - return m_addr; + return m_data.addr; } u32 size() const { - return m_size; + return m_data.size; } /* @@ -614,22 +605,22 @@ namespace vm template operator const ps3::ptr() const { - return ps3::ptr::make(m_addr); + return ps3::ptr::make(m_data.addr); } template operator const ps3::ptr() const { - return ps3::ptr::make(m_addr); + return ps3::ptr::make(m_data.addr); } operator T&() { - return *m_ptr; + return *m_data.ptr; } operator const T&() const { - return *m_ptr; + return *m_data.ptr; } }; } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/CB_FUNC.h b/rpcs3/Emu/SysCalls/CB_FUNC.h index 35588da48a..ed711656c1 100644 --- a/rpcs3/Emu/SysCalls/CB_FUNC.h +++ b/rpcs3/Emu/SysCalls/CB_FUNC.h @@ -24,9 +24,9 @@ namespace cb_detail { static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_GENERAL"); - __forceinline static void set_value(PPUThread& CPU, const T arg) + __forceinline static void set_value(PPUThread& CPU, const T& arg) { - (T&)CPU.GPR[g_count + 2] = arg; + CPU.GPR[g_count + 2] = cast_ppu_gpr::func(arg); } }; @@ -35,7 +35,7 @@ namespace cb_detail { static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_FLOAT"); - __forceinline static void set_value(PPUThread& CPU, const T arg) + __forceinline static void set_value(PPUThread& CPU, const T& arg) { CPU.FPR[f_count] = arg; } @@ -46,9 +46,9 @@ namespace cb_detail { static_assert(std::is_same::value, "Invalid callback argument type for ARG_VECTOR"); - __forceinline static void set_value(PPUThread& CPU, const T arg) + __forceinline static void set_value(PPUThread& CPU, const T& arg) { - (T&)CPU.VPR[v_count + 1] = arg; + CPU.VPR[v_count + 1] = arg; } }; @@ -59,13 +59,11 @@ namespace cb_detail static_assert(v_count <= 12, "TODO: Unsupported stack argument type (vector)"); static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_STACK"); - __forceinline static void set_value(PPUThread& CPU, const T arg) + __forceinline static void set_value(PPUThread& CPU, const T& arg) { const int stack_pos = 0x70 + (g_count - 9) * 8 - FIXED_STACK_FRAME_SIZE; static_assert(stack_pos < 0, "TODO: Increase fixed stack frame size (arg count limit broken)"); - u64 value = 0; - (T&)value = arg; - vm::write64(CPU.GPR[1] + stack_pos, value); + vm::write64(CPU.GPR[1] + stack_pos, cast_ppu_gpr::func(arg)); } }; @@ -121,11 +119,11 @@ namespace cb_detail template struct _func_res { - static_assert(sizeof(T) == 16, "Invalid callback result type for ARG_VECTOR"); + static_assert(std::is_same::value, "Invalid callback result type for ARG_VECTOR"); __forceinline static T get_value(const PPUThread& CPU) { - return (T&)CPU.VPR[2]; + return CPU.VPR[2]; } }; @@ -167,8 +165,8 @@ namespace vm template __forceinline RT _ptr_base::call(CPUThread& CPU, T... args) const { - const u32 pc = vm::get_ref>(m_addr); - const u32 rtoc = vm::get_ref>(m_addr + 4); + const u32 pc = vm::get_ref>((u32)m_addr); + const u32 rtoc = vm::get_ref>((u32)m_addr + 4); return cb_detail::_func_caller::call(static_cast(CPU), pc, rtoc, args...); } diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index 111c4333b2..d1d5f38dd1 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -46,11 +46,11 @@ namespace detail template struct bind_arg { - static_assert(sizeof(T) == 16, "Invalid function argument type for ARG_VECTOR"); + static_assert(std::is_same::value, "Invalid function argument type for ARG_VECTOR"); static __forceinline T func(PPUThread& CPU) { - return (T&)CPU.VPR[v_count + 1]; + return CPU.VPR[v_count + 1]; } }; @@ -75,9 +75,9 @@ namespace detail static_assert(type == ARG_GENERAL, "Wrong use of bind_result template"); static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_GENERAL"); - static __forceinline void func(PPUThread& CPU, T result) + static __forceinline void func(PPUThread& CPU, const T& result) { - (T&)CPU.GPR[3] = result; + CPU.GPR[3] = cast_ppu_gpr::func(result); } }; @@ -86,7 +86,7 @@ namespace detail { static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT"); - static __forceinline void func(PPUThread& CPU, T result) + static __forceinline void func(PPUThread& CPU, const T& result) { CPU.FPR[1] = (double)result; } @@ -95,11 +95,11 @@ namespace detail template struct bind_result { - static_assert(sizeof(T) == 16, "Invalid function result type for ARG_VECTOR"); + static_assert(std::is_same::value, "Invalid function result type for ARG_VECTOR"); - static __forceinline void func(PPUThread& CPU, const T result) + static __forceinline void func(PPUThread& CPU, const T& result) { - (T&)CPU.VPR[2] = result; + CPU.VPR[2] = result; } };