From 36e691c2db0bb8a7010fcfc1c98f87f3c6ab1170 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 27 Aug 2014 01:09:50 +0400 Subject: [PATCH] Small fix --- rpcs3/Emu/SysCalls/SC_FUNC.h | 44 ++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index 4a773bcf6c..aa3cc4c5db 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -23,26 +23,46 @@ namespace detail template struct bind_arg { - static __forceinline T func(PPUThread& CPU) { return (T&)CPU.GPR[g_count + 2]; } + static_assert(sizeof(T) <= 8, "Wrong argument type for ARG_GENERAL"); + + static __forceinline T func(PPUThread& CPU) + { + return (T&)CPU.GPR[g_count + 2]; + } }; template struct bind_arg { - static __forceinline T func(PPUThread& CPU) { return (T&)CPU.FPR[f_count]; } + static_assert(sizeof(T) <= 8, "Wrong argument type for ARG_FLOAT"); + + static __forceinline T func(PPUThread& CPU) + { + return (T&)CPU.FPR[f_count]; + } }; template struct bind_arg { - static_assert(v_count == 0, "ARG_VECTOR not supported"); - static __forceinline T func(PPUThread& CPU) { return T(); } + static_assert(sizeof(T) == 16, "Wrong argument type for ARG_VECTOR"); + + static __forceinline T func(PPUThread& CPU) + { + return (T&)CPU.VPR[v_count + 1]._u128; + } }; 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)); } + static_assert(sizeof(T) <= 8 && v_count <= 12, "Wrong argument type for ARG_STACK"); + + static __forceinline T func(PPUThread& CPU) + { + const u64 res = CPU.GetStackArg(8 + std::max(g_count - 8, 0) + std::max(f_count - 12, 0)); + return (T&)res; + } }; template @@ -96,16 +116,16 @@ namespace detail template static __forceinline std::tuple iterate(PPUThread& CPU) { + static_assert(!std::is_pointer::value, "Invalid function argument type: pointer"); // TODO: check calculations - const bind_arg_type t = std::is_floating_point::value + const bool is_float = std::is_floating_point::value; + const bind_arg_type t = is_float ? ((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)); + const int g = g_count + (is_float ? 0 : 1); + const int f = f_count + (is_float ? 1 : 0); + const int v = v_count; // TODO: vector argument support (if possible) + return std::tuple_cat(std::tuple(bind_arg::func(CPU)), iterate(CPU)); } template