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.cpp b/rpcs3/Emu/Memory/vm.cpp index dbac50e797..6379fabb02 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -1,5 +1,7 @@ #include "stdafx.h" #include "Memory.h" +#include "Emu/CPU/CPUThread.h" +#include "Emu/Cell/PPUThread.h" namespace vm { @@ -143,4 +145,84 @@ namespace vm { Memory.Close(); } + + u32 stack_push(CPUThread& CPU, u32 size, u32 align_v, u32& old_pos) + { + switch (CPU.GetType()) + { + case CPU_THREAD_PPU: + { + PPUThread& PPU = static_cast(CPU); + + assert(align_v); + old_pos = (u32)PPU.GPR[1]; + PPU.GPR[1] -= align(size, 8); // room minimal possible size + PPU.GPR[1] &= ~(align_v - 1); // fix stack alignment + + if (PPU.GPR[1] < CPU.GetStackAddr()) + { + // stack overflow + PPU.GPR[1] = old_pos; + return 0; + } + else + { + return (u32)PPU.GPR[1]; + } + } + + case CPU_THREAD_SPU: + case CPU_THREAD_RAW_SPU: + { + assert(!"stack_push(): SPU not supported"); + return 0; + } + + case CPU_THREAD_ARMv7: + { + assert(!"stack_push(): ARMv7 not supported"); + return 0; + } + + default: + { + assert(!"stack_push(): invalid thread type"); + return 0; + } + } + } + + void stack_pop(CPUThread& CPU, u32 addr, u32 old_pos) + { + switch (CPU.GetType()) + { + case CPU_THREAD_PPU: + { + PPUThread& PPU = static_cast(CPU); + + assert(PPU.GPR[1] == addr); + PPU.GPR[1] = old_pos; + return; + } + + case CPU_THREAD_SPU: + case CPU_THREAD_RAW_SPU: + { + assert(!"stack_pop(): SPU not supported"); + return; + } + + case CPU_THREAD_ARMv7: + { + assert(!"stack_pop(): ARMv7 not supported"); + return; + } + + default: + { + assert(!"stack_pop(): invalid thread type"); + return; + } + } + } } \ No newline at end of file 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 c3d637abda..0975a00913 100644 --- a/rpcs3/Emu/Memory/vm_var.h +++ b/rpcs3/Emu/Memory/vm_var.h @@ -1,5 +1,7 @@ #pragma once +class CPUThread; + namespace vm { template @@ -495,4 +497,130 @@ namespace vm return (NT*)(m_ptr + offset); } }; + + template + class stackvar + { + struct stack_allocation + { + T* ptr; + u32 addr; + u32 size; + u32 align; + u32 old_pos; + + stack_allocation(CPUThread& CPU, u32 size, u32 align) + : size(size) + , align(align) + { + 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_data(CPU, size, align) + , m_thread(CPU) + { + } + + stackvar(const stackvar& r) + : m_data(r.m_thread, r.m_data.m_size, r.m_data.m_align) + , m_thread(r.m_thread) + { + *m_data.ptr = *r.m_data.ptr; + } + + stackvar(stackvar&& r) = delete; + + ~stackvar() + { + 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_data.ptr; + } + + const T* operator -> () const + { + return m_data.ptr; + } + + T* get_ptr() + { + return m_data.ptr; + } + + const T* get_ptr() const + { + return m_data.ptr; + } + + T& value() + { + return *m_data.ptr; + } + + const T& value() const + { + return *m_data.ptr; + } + + u32 addr() const + { + return m_data.addr; + } + + u32 size() const + { + return m_data.size; + } + + /* + operator const ref() const + { + return addr(); + } + */ + + template operator const ps3::ptr() const + { + return ps3::ptr::make(m_data.addr); + } + + template operator const ps3::ptr() const + { + return ps3::ptr::make(m_data.addr); + } + + operator T&() + { + return *m_data.ptr; + } + + operator const T&() const + { + 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/Modules/cellFont.cpp b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp index 0d709d6d39..69199e2f2c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFont.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp @@ -36,11 +36,11 @@ int cellFontGetRevisionFlags(vm::ptr> revisionFlags) return CELL_FONT_OK; } -int cellFontInit(vm::ptr config) +int cellFontInit(PPUThread& CPU, vm::ptr config) { cellFont->Log("cellFontInit(config=0x%x)", config.addr()); - vm::var> revisionFlags; + vm::stackvar> revisionFlags(CPU); revisionFlags.value() = 0; cellFontGetRevisionFlags(revisionFlags); return cellFontInitializeWithRevision(revisionFlags.value(), config); @@ -101,7 +101,7 @@ int cellFontOpenFontFile(vm::ptr library, vm::ptr f return ret; } -int cellFontOpenFontset(vm::ptr library, vm::ptr fontType, vm::ptr font) +int cellFontOpenFontset(PPUThread& CPU, vm::ptr library, vm::ptr fontType, vm::ptr font) { cellFont->Log("cellFontOpenFontset(library_addr=0x%x, fontType_addr=0x%x, font_addr=0x%x)", library.addr(), fontType.addr(), font.addr()); @@ -177,7 +177,7 @@ int cellFontOpenFontset(vm::ptr library, vm::ptr return CELL_FONT_ERROR_NO_SUPPORT_FONTSET; } - vm::var f((u32)file.length() + 1, 1); + vm::stackvar f(CPU, (u32)file.length() + 1, 1); memcpy(f.get_ptr(), file.c_str(), file.size() + 1); int ret = cellFontOpenFontFile(library, f, 0, 0, font); //TODO: Find the correct values of subNum, uniqueId font->origin = CELL_FONT_OPEN_FONTSET; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 227d43ca96..e2a82abf0f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -201,7 +201,7 @@ int cellGameContentPermit(vm::ptr contentInfoPath, vm: return CELL_GAME_RET_OK; } -int cellGameDataCheckCreate2(u32 version, vm::ptr dirName, u32 errDialog, +int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, vm::ptr cbResult, vm::ptr get, vm::ptr set)> funcStat, u32 container) { cellGame->Warning("cellGameDataCheckCreate(2)(version=0x%x, dirName_addr=0x%x, errDialog=0x%x, funcStat_addr=0x%x, container=%d)", @@ -238,10 +238,9 @@ int cellGameDataCheckCreate2(u32 version, vm::ptr dirName, u32 errDi return CELL_GAMEDATA_ERROR_BROKEN; } - // TODO: use memory container - vm::var cbResult; - vm::var cbGet; - vm::var cbSet; + vm::stackvar cbResult(CPU); + vm::stackvar cbGet(CPU); + vm::stackvar cbSet(CPU); cbGet.value() = {}; @@ -307,11 +306,11 @@ int cellGameDataCheckCreate2(u32 version, vm::ptr dirName, u32 errDi } } -int cellGameDataCheckCreate(u32 version, vm::ptr dirName, u32 errDialog, +int cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, vm::ptr cbResult, vm::ptr get, vm::ptr set)> funcStat, u32 container) { // TODO: almost identical, the only difference is that this function will always calculate the size of game data - return cellGameDataCheckCreate2(version, dirName, errDialog, funcStat, container); + return cellGameDataCheckCreate2(CPU, version, dirName, errDialog, funcStat, container); } int cellGameCreateGameData(vm::ptr init, vm::ptr tmp_contentInfoPath, vm::ptr tmp_usrdirPath) diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.h b/rpcs3/Emu/SysCalls/Modules/cellGame.h index 0e7f6e3e95..1ccda34eb1 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.h @@ -199,4 +199,4 @@ struct CellGameDataStatSet { vm::bptr setParam; be_t reserved; -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index fca2ca40f7..1d9c1ee6d6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -1287,7 +1287,7 @@ s32 _cellSyncLFQueueCompletePushPointer2(vm::ptr queue, s32 poi return syncLFQueueCompletePushPointer2(queue, pointer, fpSendSignal); } -s32 _cellSyncLFQueuePushBody(vm::ptr queue, vm::ptr buffer, u32 isBlocking) +s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm::ptr buffer, u32 isBlocking) { // cellSyncLFQueuePush has 1 in isBlocking param, cellSyncLFQueueTryPush has 0 cellSync->Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.addr(), buffer.addr(), isBlocking); @@ -1302,10 +1302,8 @@ s32 _cellSyncLFQueuePushBody(vm::ptr queue, vm::ptr } s32 position; - //syncLFQueueDump(queue); - #ifdef PRX_DEBUG - vm::var> position_v; + vm::stackvar> position_v(CPU); #endif while (true) { @@ -1314,7 +1312,7 @@ s32 _cellSyncLFQueuePushBody(vm::ptr queue, vm::ptr if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { #ifdef PRX_DEBUG_XXX - res = cb_caller, u32, u32, u64>::call(GetCurrentPPUThread(), libsre + 0x24B0, libsre_rtoc, + res = cb_call, u32, u32, u64>(CPU, libsre + 0x24B0, libsre_rtoc, queue, position_v.addr(), isBlocking, 0); position = position_v->ToLE(); #else @@ -1324,7 +1322,7 @@ s32 _cellSyncLFQueuePushBody(vm::ptr queue, vm::ptr else { #ifdef PRX_DEBUG - res = cb_call, u32, u32, u64>(GetCurrentPPUThread(), libsre + 0x3050, libsre_rtoc, + res = cb_call, u32, u32, u64>(CPU, libsre + 0x3050, libsre_rtoc, queue, position_v.addr(), isBlocking, 0); position = position_v->ToLE(); #else @@ -1332,9 +1330,6 @@ s32 _cellSyncLFQueuePushBody(vm::ptr queue, vm::ptr #endif } - //LOG_NOTICE(HLE, "... position = %d", position); - //syncLFQueueDump(queue); - if (!isBlocking || res != CELL_SYNC_ERROR_AGAIN) { if (res) @@ -1360,7 +1355,7 @@ s32 _cellSyncLFQueuePushBody(vm::ptr queue, vm::ptr if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { #ifdef PRX_DEBUG_XXX - res = cb_caller, s32, u64>::call(GetCurrentPPUThread(), libsre + 0x26C0, libsre_rtoc, + res = cb_call, s32, u64>(CPU, libsre + 0x26C0, libsre_rtoc, queue, position, 0); #else res = syncLFQueueCompletePushPointer(queue, position, nullptr); @@ -1369,14 +1364,13 @@ s32 _cellSyncLFQueuePushBody(vm::ptr queue, vm::ptr else { #ifdef PRX_DEBUG - res = cb_call, s32, u64>(GetCurrentPPUThread(), libsre + 0x355C, libsre_rtoc, + res = cb_call, s32, u64>(CPU, libsre + 0x355C, libsre_rtoc, queue, position, 0); #else res = syncLFQueueCompletePushPointer2(queue, position, nullptr); #endif } - //syncLFQueueDump(queue); return res; } @@ -1669,7 +1663,7 @@ s32 _cellSyncLFQueueCompletePopPointer2(vm::ptr queue, s32 poin return syncLFQueueCompletePopPointer2(queue, pointer, fpSendSignal, noQueueFull); } -s32 _cellSyncLFQueuePopBody(vm::ptr queue, vm::ptr buffer, u32 isBlocking) +s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm::ptr buffer, u32 isBlocking) { // cellSyncLFQueuePop has 1 in isBlocking param, cellSyncLFQueueTryPop has 0 cellSync->Warning("_cellSyncLFQueuePopBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.addr(), buffer.addr(), isBlocking); @@ -1685,7 +1679,7 @@ s32 _cellSyncLFQueuePopBody(vm::ptr queue, vm::ptr buffer s32 position; #ifdef PRX_DEBUG - vm::var> position_v; + vm::stackvar> position_v(CPU); #endif while (true) { @@ -1693,7 +1687,7 @@ s32 _cellSyncLFQueuePopBody(vm::ptr queue, vm::ptr buffer if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { #ifdef PRX_DEBUG_XXX - res = cb_caller, u32, u32, u64, u64>::call(GetCurrentPPUThread(), libsre + 0x2A90, libsre_rtoc, + res = cb_call, u32, u32, u64, u64>(CPU, libsre + 0x2A90, libsre_rtoc, queue, position_v.addr(), isBlocking, 0, 0); position = position_v->ToLE(); #else @@ -1703,7 +1697,7 @@ s32 _cellSyncLFQueuePopBody(vm::ptr queue, vm::ptr buffer else { #ifdef PRX_DEBUG - res = cb_call, u32, u32, u64>(GetCurrentPPUThread(), libsre + 0x39AC, libsre_rtoc, + res = cb_call, u32, u32, u64>(CPU, libsre + 0x39AC, libsre_rtoc, queue, position_v.addr(), isBlocking, 0); position = position_v->ToLE(); #else @@ -1736,7 +1730,7 @@ s32 _cellSyncLFQueuePopBody(vm::ptr queue, vm::ptr buffer if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { #ifdef PRX_DEBUG_XXX - res = cb_caller, s32, u64, u64>::call(GetCurrentPPUThread(), libsre + 0x2CA8, libsre_rtoc, + res = cb_call, s32, u64, u64>(CPU, libsre + 0x2CA8, libsre_rtoc, queue, position, 0, 0); #else res = syncLFQueueCompletePopPointer(queue, position, nullptr, 0); @@ -1745,7 +1739,7 @@ s32 _cellSyncLFQueuePopBody(vm::ptr queue, vm::ptr buffer else { #ifdef PRX_DEBUG - res = cb_call, s32, u64, u64>(GetCurrentPPUThread(), libsre + 0x3EB8, libsre_rtoc, + res = cb_call, s32, u64, u64>(CPU, libsre + 0x3EB8, libsre_rtoc, queue, position, 0, 0); #else res = syncLFQueueCompletePopPointer2(queue, position, nullptr, 0); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 44458c905c..06c419b4b8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -835,10 +835,10 @@ int cellWebBrowserEstimate2(const vm::ptr config, v return CELL_OK; } -extern int cellGameDataCheckCreate2(u32 version, vm::ptr dirName, u32 errDialog, +extern int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, vm::ptr cbResult, vm::ptr get, vm::ptr set)> funcStat, u32 container); -extern int cellGameDataCheckCreate(u32 version, vm::ptr dirName, u32 errDialog, +extern int cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, vm::ptr cbResult, vm::ptr get, vm::ptr set)> funcStat, u32 container); extern void cellSysutil_SaveData_init(); diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index faf91a529f..767c3c04da 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -286,7 +286,7 @@ s32 _sys_spu_printf_finalize() return CELL_OK; } -s64 _sys_spu_printf_attach_group(u32 group) +s32 _sys_spu_printf_attach_group(PPUThread& CPU, u32 group) { sysPrxForUser->Warning("_sys_spu_printf_attach_group(group=%d)", group); @@ -295,10 +295,10 @@ s64 _sys_spu_printf_attach_group(u32 group) return CELL_ESTAT; } - return spu_printf_agcb(group); + return spu_printf_agcb.call(CPU, group); } -s64 _sys_spu_printf_detach_group(u32 group) +s32 _sys_spu_printf_detach_group(PPUThread& CPU, u32 group) { sysPrxForUser->Warning("_sys_spu_printf_detach_group(group=%d)", group); @@ -307,10 +307,10 @@ s64 _sys_spu_printf_detach_group(u32 group) return CELL_ESTAT; } - return spu_printf_dgcb(group); + return spu_printf_dgcb.call(CPU, group); } -s64 _sys_spu_printf_attach_thread(u32 thread) +s32 _sys_spu_printf_attach_thread(PPUThread& CPU, u32 thread) { sysPrxForUser->Warning("_sys_spu_printf_attach_thread(thread=%d)", thread); @@ -319,10 +319,10 @@ s64 _sys_spu_printf_attach_thread(u32 thread) return CELL_ESTAT; } - return spu_printf_atcb(thread); + return spu_printf_atcb.call(CPU, thread); } -s64 _sys_spu_printf_detach_thread(u32 thread) +s32 _sys_spu_printf_detach_thread(PPUThread& CPU, u32 thread) { sysPrxForUser->Warning("_sys_spu_printf_detach_thread(thread=%d)", thread); @@ -331,7 +331,7 @@ s64 _sys_spu_printf_detach_thread(u32 thread) return CELL_ESTAT; } - return spu_printf_dtcb(thread); + return spu_printf_dtcb.call(CPU, thread); } s32 _sys_snprintf(vm::ptr dst, u32 count, vm::ptr fmt) // va_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; } }; diff --git a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp index 60e09c82fc..ec5e07daed 100644 --- a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp @@ -1000,13 +1000,13 @@ int cellFsAioFinish(vm::ptr mount_point) return CELL_OK; } -int cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, vm::ptr> nread) +int cellFsReadWithOffset(PPUThread& CPU, u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, vm::ptr> nread) { sys_fs->Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf_addr=0x%x, buffer_size=%lld nread=0x%llx)", fd, offset, buf.addr(), buffer_size, nread.addr()); int ret; - vm::var> oldPos, newPos; + vm::stackvar> oldPos(CPU), newPos(CPU); ret = cellFsLseek(fd, 0, CELL_SEEK_CUR, oldPos); // Save the current position if (ret) return ret; ret = cellFsLseek(fd, offset, CELL_SEEK_SET, newPos); // Move to the specified offset