diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 9654667526..0a11d9a724 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -831,93 +831,158 @@ public: ppu_thread& gpr(uint index, u64 value); }; -template +template::value> struct cast_ppu_gpr { - static_assert(sizeof(T) <= 8, "Invalid type for cast_ppu_gpr"); + static_assert(is_enum, "Invalid type for cast_ppu_gpr"); + + typedef typename std::underlying_type::type underlying_type; __forceinline static u64 to_gpr(const T& value) { - u64 result = 0; - (T&)result = value; - return result; + return cast_ppu_gpr::to_gpr(static_cast(value)); } -}; -template -struct cast_ppu_gpr -{ - __forceinline static u64 to_gpr(const T& value) + __forceinline static T from_gpr(const u64 reg) { - return (u8&)value; - } -}; - -template -struct cast_ppu_gpr -{ - __forceinline static u64 to_gpr(const T& value) - { - return (u16&)value; - } -}; - -template -struct cast_ppu_gpr -{ - __forceinline static u64 to_gpr(const T& value) - { - return (u32&)value; - } -}; - -template -struct cast_ppu_gpr -{ - __forceinline static u64 to_gpr(const T& value) - { - return (u64&)value; + return static_cast(cast_ppu_gpr::from_gpr(reg)); } }; template<> -struct cast_ppu_gpr +struct cast_ppu_gpr +{ + __forceinline static u64 to_gpr(const u8& value) + { + return value; + } + + __forceinline static u8 from_gpr(const u64 reg) + { + return static_cast(reg); + } +}; + +template<> +struct cast_ppu_gpr +{ + __forceinline static u64 to_gpr(const u16& value) + { + return value; + } + + __forceinline static u16 from_gpr(const u64 reg) + { + return static_cast(reg); + } +}; + +template<> +struct cast_ppu_gpr +{ + __forceinline static u64 to_gpr(const u32& value) + { + return value; + } + + __forceinline static u32 from_gpr(const u64 reg) + { + return static_cast(reg); + } +}; + +template<> +struct cast_ppu_gpr +{ + __forceinline static u64 to_gpr(const u64& value) + { + return value; + } + + __forceinline static u64 from_gpr(const u64 reg) + { + return reg; + } +}; + +template<> +struct cast_ppu_gpr { __forceinline static u64 to_gpr(const s8& value) { return value; } + + __forceinline static s8 from_gpr(const u64 reg) + { + return static_cast(reg); + } }; template<> -struct cast_ppu_gpr +struct cast_ppu_gpr { __forceinline static u64 to_gpr(const s16& value) { return value; } + + __forceinline static s16 from_gpr(const u64 reg) + { + return static_cast(reg); + } }; template<> -struct cast_ppu_gpr +struct cast_ppu_gpr { __forceinline static u64 to_gpr(const s32& value) { return value; } + + __forceinline static s32 from_gpr(const u64 reg) + { + return static_cast(reg); + } }; template<> -struct cast_ppu_gpr +struct cast_ppu_gpr { __forceinline static u64 to_gpr(const s64& value) { return value; } + + __forceinline static s64 from_gpr(const u64 reg) + { + return static_cast(reg); + } +}; + +template<> +struct cast_ppu_gpr +{ + __forceinline static u64 to_gpr(const bool& value) + { + return value; + } + + __forceinline static bool from_gpr(const u64 reg) + { + return (bool&)reg; + } }; template -__forceinline static u64 cast_to_ppu_gpr(const T& value) +__forceinline u64 cast_to_ppu_gpr(const T& value) { return cast_ppu_gpr::to_gpr(value); } + +template +__forceinline T cast_from_ppu_gpr(const u64 reg) +{ + return cast_ppu_gpr::from_gpr(reg); +} diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index d0c061c096..297c6da7ef 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -535,3 +535,22 @@ namespace fmt } }; } + +// external specializations for PPU GPR (SC_FUNC.h, CB_FUNC.h) + +template +struct cast_ppu_gpr; + +template +struct cast_ppu_gpr, false> +{ + __forceinline static u64 to_gpr(const vm::ps3::ptr& value) + { + return value.addr(); + } + + __forceinline static vm::ps3::ptr from_gpr(const u64 reg) + { + return vm::ps3::ptr::make(cast_ppu_gpr::from_gpr(reg)); + } +}; diff --git a/rpcs3/Emu/Memory/vm_ref.h b/rpcs3/Emu/Memory/vm_ref.h index 7a21693bf0..79045a4118 100644 --- a/rpcs3/Emu/Memory/vm_ref.h +++ b/rpcs3/Emu/Memory/vm_ref.h @@ -147,3 +147,22 @@ namespace fmt } }; } + +// external specializations for PPU GPR (SC_FUNC.h, CB_FUNC.h) + +template +struct cast_ppu_gpr; + +template +struct cast_ppu_gpr, false> +{ + __forceinline static u64 to_gpr(const vm::ps3::ref& value) + { + return value.addr(); + } + + __forceinline static vm::ps3::ref from_gpr(const u64 reg) + { + return vm::ps3::ref::make(cast_ppu_gpr::from_gpr(reg)); + } +}; diff --git a/rpcs3/Emu/SysCalls/CB_FUNC.h b/rpcs3/Emu/SysCalls/CB_FUNC.h index e567225185..403a703db5 100644 --- a/rpcs3/Emu/SysCalls/CB_FUNC.h +++ b/rpcs3/Emu/SysCalls/CB_FUNC.h @@ -37,7 +37,7 @@ namespace cb_detail __forceinline static void set_value(PPUThread& CPU, const T& arg) { - CPU.FPR[f_count] = arg; + CPU.FPR[f_count] = static_cast(arg); } }; @@ -101,7 +101,7 @@ namespace cb_detail __forceinline static T get_value(const PPUThread& CPU) { - return (T&)CPU.GPR[3]; + return cast_from_ppu_gpr(CPU.GPR[3]); } }; @@ -112,7 +112,7 @@ namespace cb_detail __forceinline static T get_value(const PPUThread& CPU) { - return (T)CPU.FPR[1]; + return static_cast(CPU.FPR[1]); } }; diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index ad405eac7a..0fd40217ca 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -28,7 +28,7 @@ namespace detail static __forceinline T func(PPUThread& CPU) { - return (T&)CPU.GPR[g_count + 2]; + return cast_from_ppu_gpr(CPU.GPR[g_count + 2]); } }; @@ -39,7 +39,7 @@ namespace detail static __forceinline T func(PPUThread& CPU) { - return (T)CPU.FPR[f_count]; + return static_cast(CPU.FPR[f_count]); } }; @@ -65,7 +65,7 @@ namespace detail { // TODO: check stack argument displacement const u64 res = CPU.GetStackArg(8 + std::max(g_count - 8, 0) + std::max(f_count - 13, 0) + std::max(v_count - 12, 0)); - return (T&)res; + return cast_from_ppu_gpr(res); } }; @@ -88,7 +88,7 @@ namespace detail static __forceinline void func(PPUThread& CPU, const T& result) { - CPU.FPR[1] = result; + CPU.FPR[1] = static_cast(result); } };