From 5d3a612003f0c10372028dba17767d5e86f89432 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 26 Aug 2014 18:38:14 +0400 Subject: [PATCH] SC_FUNC.h rewritten Now float arguments should work correctly --- rpcs3/Emu/Memory/Memory.h | 4 + rpcs3/Emu/SysCalls/Modules.h | 1 - rpcs3/Emu/SysCalls/SC_FUNC.h | 511 ++++++++------------------------ rpcs3/Emu/SysCalls/SysCalls.cpp | 6 +- 4 files changed, 135 insertions(+), 387 deletions(-) diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 75b78e6eaa..8ce65be932 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -754,6 +754,10 @@ public: { } + mem_class_t() : m_addr(0) + { + } + template u32 operator += (T right) { mem_t& m((mem_t&)*this); diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index a5a6f6890a..776ab30200 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -141,7 +141,6 @@ __forceinline void Module::AddFuncSub(const char group[8], const u64 ops[], cons { if (!ops[0]) return; - //TODO: track down where this is supposed to be deleted SFunc* sf = new SFunc; sf->ptr = (void *)func; sf->func = bind_func(func); diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index 7e3ecc41ad..4a773bcf6c 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -1,414 +1,159 @@ #pragma once #include "Emu/Cell/PPUThread.h" -#define RESULT(x) CPU.GPR[3] = (x) - class func_caller { public: virtual void operator()() = 0; }; - -template -struct get_arg; - -template -struct get_arg // not fp, not ptr, 1..8 +namespace detail { - static __forceinline T func(PPUThread& CPU) { return (T&)CPU.GPR[i + 2]; } -}; + enum bind_arg_type + { + ARG_GENERAL, + ARG_FLOAT, + ARG_VECTOR, + ARG_STACK, + }; -template -struct get_arg // ptr, 1..8 -{ - static_assert(i == 0, "Invalid function argument type: pointer"); - static __forceinline T func(PPUThread& CPU) { return nullptr; } -}; + template + struct bind_arg; -template -struct get_arg // fp, 1..12 -{ - static __forceinline T func(PPUThread& CPU) { return CPU.FPR[i]; } -}; + template + struct bind_arg + { + static __forceinline T func(PPUThread& CPU) { return (T&)CPU.GPR[g_count + 2]; } + }; -template -struct get_arg // not fp, not ptr, 9..12 -{ - static __forceinline T func(PPUThread& CPU) { u64 res = CPU.GetStackArg(i); return (T&)res; } -}; + template + struct bind_arg + { + static __forceinline T func(PPUThread& CPU) { return (T&)CPU.FPR[f_count]; } + }; -template -struct get_arg // ptr, 9..12 -{ - static_assert(i == 0, "Invalid function argument type: pointer"); - static __forceinline T func(PPUThread& CPU) { return nullptr; } -}; + template + struct bind_arg + { + static_assert(v_count == 0, "ARG_VECTOR not supported"); + static __forceinline T func(PPUThread& CPU) { return T(); } + }; -#define ARG(n) get_arg<((n) > 8), std::is_floating_point::value, std::is_pointer::value, T##n, n>::func(CPU) + template + struct bind_arg + { + static __forceinline T func(PPUThread& CPU) { return CPU.GetStackArg(8 + std::max(g_count - 8, 0) + std::max(f_count - 12, 0)); } + }; -template -class binder_func_0 : public func_caller -{ - typedef TR (*func_t)(); - const func_t m_call; + template + struct bind_result + { + static __forceinline void func(PPUThread& CPU, T value) + { + static_assert(!std::is_pointer::value, "Invalid function result type: pointer"); + if (std::is_floating_point::value) + { + (T&)CPU.FPR[1] = value; + } + else + { + (T&)CPU.GPR[3] = value; + } + } + }; -public: - binder_func_0(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call()); } -}; + template + struct call_impl + { + static __forceinline RT call(F f, Tuple && t) + { + return call_impl::call(f, std::forward(t)); + } + }; -template<> -class binder_func_0 : public func_caller -{ - typedef void (*func_t)(); - const func_t m_call; + template + struct call_impl + { + static __forceinline RT call(F f, Tuple && t) + { + return f(std::get(std::forward(t))...); + } + }; -public: - binder_func_0(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(); } -}; + template + static __forceinline RT call(F f, Tuple && t) + { + typedef typename std::decay::type ttype; + return detail::call_impl::value, std::tuple_size::value>::call(f, std::forward(t)); + } -template -class binder_func_1 : public func_caller -{ - typedef TR (*func_t)(T1); - const func_t m_call; + template + static __forceinline std::tuple<> iterate(PPUThread& CPU) + { + return std::tuple<>(); + } -public: - binder_func_1(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1))); } -}; + template + static __forceinline std::tuple iterate(PPUThread& CPU) + { + // TODO: check calculations + const bind_arg_type t = std::is_floating_point::value + ? ((f_count >= 12) ? ARG_STACK : ARG_FLOAT) + : ((g_count >= 8) ? ARG_STACK : ARG_GENERAL); + const int g = g_count + (std::is_floating_point::value ? 0 : 1); + const int f = f_count + (std::is_floating_point::value ? 1 : 0); + const int v = v_count; // TODO: vector arguments support (if possible) + static_assert(!v_count, "ARG_VECTOR not supported"); + static_assert(!std::is_pointer::value, "Invalid function argument type: pointer"); + return std::tuple_cat, std::tuple>(std::tuple(bind_arg::func(CPU)), iterate(CPU)); + } -template -class binder_func_1 : public func_caller -{ - typedef void (*func_t)(T1); - const func_t m_call; + template + class func_binder; -public: - binder_func_1(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1)); } -}; + template + class func_binder : public func_caller + { + typedef void(*func_t)(TA...); + const func_t m_call; -template -class binder_func_2 : public func_caller -{ - typedef TR (*func_t)(T1, T2); - const func_t m_call; + public: + func_binder(func_t call) + : func_caller() + , m_call(call) + { + } -public: - binder_func_2(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2))); } -}; + virtual void operator()() + { + declCPU(); + call(m_call, iterate<0, 0, 0, TA...>(CPU)); + } + }; -template -class binder_func_2 : public func_caller -{ - typedef void (*func_t)(T1, T2); - const func_t m_call; + template + class func_binder : public func_caller + { + typedef TR(*func_t)(TA...); + const func_t m_call; -public: - binder_func_2(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2)); } -}; + public: + func_binder(func_t call) + : func_caller() + , m_call(call) + { + } -template -class binder_func_3 : public func_caller -{ - typedef TR (*func_t)(T1, T2, T3); - const func_t m_call; - -public: - binder_func_3(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3))); } -}; - -template -class binder_func_3 : public func_caller -{ - typedef void (*func_t)(T1, T2, T3); - const func_t m_call; - -public: - binder_func_3(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3)); } -}; - -template -class binder_func_4 : public func_caller -{ - typedef TR (*func_t)(T1, T2, T3, T4); - const func_t m_call; - -public: - binder_func_4(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4))); } -}; - -template -class binder_func_4 : public func_caller -{ - typedef void (*func_t)(T1, T2, T3, T4); - const func_t m_call; - -public: - binder_func_4(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4)); } -}; - -template -class binder_func_5 : public func_caller -{ - typedef TR (*func_t)(T1, T2, T3, T4, T5); - const func_t m_call; - -public: - binder_func_5(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5))); } -}; - -template -class binder_func_5 : public func_caller -{ - typedef void (*func_t)(T1, T2, T3, T4, T5); - const func_t m_call; - -public: - binder_func_5(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5)); } -}; - -template -class binder_func_6 : public func_caller -{ - typedef TR (*func_t)(T1, T2, T3, T4, T5, T6); - const func_t m_call; - -public: - binder_func_6(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6))); } -}; - -template -class binder_func_6 : public func_caller -{ - typedef void (*func_t)(T1, T2, T3, T4, T5, T6); - const func_t m_call; - -public: - binder_func_6(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6)); } -}; - -template -class binder_func_7 : public func_caller -{ - typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7); - const func_t m_call; - -public: - binder_func_7(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7))); } -}; - -template -class binder_func_7 : public func_caller -{ - typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7); - const func_t m_call; - -public: - binder_func_7(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7)); } -}; - -template -class binder_func_8 : public func_caller -{ - typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8); - const func_t m_call; - -public: - binder_func_8(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8))); } -}; - -template -class binder_func_8 : public func_caller -{ - typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8); - const func_t m_call; - -public: - binder_func_8(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8)); } -}; - -template -class binder_func_9 : public func_caller -{ - typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9); - const func_t m_call; - -public: - binder_func_9(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9))); } -}; - -template -class binder_func_9 : public func_caller -{ - typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9); - const func_t m_call; - -public: - binder_func_9(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9)); } -}; - -template -class binder_func_10 : public func_caller -{ - typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10); - const func_t m_call; - -public: - binder_func_10(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10))); } -}; - -template -class binder_func_10 : public func_caller -{ - typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10); - const func_t m_call; - -public: - binder_func_10(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10)); } -}; - -template -class binder_func_11 : public func_caller -{ - typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11); - const func_t m_call; - -public: - binder_func_11(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10), ARG(11))); } -}; - -template -class binder_func_11 : public func_caller -{ - typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11); - const func_t m_call; - -public: - binder_func_11(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10), ARG(11)); } -}; - -template -class binder_func_12 : public func_caller -{ - typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12); - const func_t m_call; - -public: - binder_func_12(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10), ARG(11), ARG(12))); } -}; - -template -class binder_func_12 : public func_caller -{ - typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12); - const func_t m_call; - -public: - binder_func_12(func_t call) : func_caller(), m_call(call) {} - virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10), ARG(11), ARG(12)); } -}; - -#undef ARG - -template -func_caller* bind_func(TR (*call)()) -{ - return new binder_func_0(call); + virtual void operator()() + { + declCPU(); + bind_result::func(CPU, call(m_call, iterate<0, 0, 0, TA...>(CPU))); + } + }; } -template -func_caller* bind_func(TR (*call)(T1)) +template +func_caller* bind_func(TR(*call)(TA...)) { - return new binder_func_1(call); -} - -template -func_caller* bind_func(TR (*call)(T1, T2)) -{ - return new binder_func_2(call); -} - -template -func_caller* bind_func(TR (*call)(T1, T2, T3)) -{ - return new binder_func_3(call); -} - -template -func_caller* bind_func(TR (*call)(T1, T2, T3, T4)) -{ - return new binder_func_4(call); -} - -template -func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5)) -{ - return new binder_func_5(call); -} - -template -func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6)) -{ - return new binder_func_6(call); -} - -template -func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7)) -{ - return new binder_func_7(call); -} - -template -func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8)) -{ - return new binder_func_8(call); -} - -template -func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9)) -{ - return new binder_func_9(call); -} - -template -func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)) -{ - return new binder_func_10(call); -} - -template -func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)) -{ - return new binder_func_11(call); -} - -template -func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)) -{ - return new binder_func_12(call); -} + return new detail::func_binder(call); +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index ec87d6c287..999f736df0 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -924,7 +924,7 @@ void default_syscall() case 988: LOG_WARNING(HLE, "SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%llx", CPU.GPR[3], CPU.GPR[4], CPU.PC); - RESULT(0); + CPU.GPR[3] = 0; return; case 999: @@ -940,7 +940,7 @@ void default_syscall() } LOG_ERROR(HLE, "Unknown syscall: %d - %08x", code, code); - RESULT(0); + CPU.GPR[3] = 0; return; } @@ -963,7 +963,7 @@ void SysCalls::DoSyscall(u32 code) LOG_ERROR(HLE, "TODO: %s", GetHLEFuncName(code).c_str()); declCPU(); - RESULT(0); + CPU.GPR[3] = 0; } IdManager& SysCallBase::GetIdManager() const