mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 12:05:23 +00:00
cast_to_ppu_gpr(), cast_from_ppu_gpr() updated
This commit is contained in:
parent
3428499492
commit
f3c9143a81
5 changed files with 153 additions and 50 deletions
|
@ -831,93 +831,158 @@ public:
|
|||
ppu_thread& gpr(uint index, u64 value);
|
||||
};
|
||||
|
||||
template<typename T, size_t size = sizeof(T)>
|
||||
template<typename T, bool is_enum = std::is_enum<T>::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<T>::type underlying_type;
|
||||
|
||||
__forceinline static u64 to_gpr(const T& value)
|
||||
{
|
||||
u64 result = 0;
|
||||
(T&)result = value;
|
||||
return result;
|
||||
return cast_ppu_gpr<underlying_type>::to_gpr(static_cast<underlying_type>(value));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct cast_ppu_gpr<T, 1>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const T& value)
|
||||
__forceinline static T from_gpr(const u64 reg)
|
||||
{
|
||||
return (u8&)value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct cast_ppu_gpr<T, 2>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const T& value)
|
||||
{
|
||||
return (u16&)value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct cast_ppu_gpr<T, 4>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const T& value)
|
||||
{
|
||||
return (u32&)value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct cast_ppu_gpr<T, 8>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const T& value)
|
||||
{
|
||||
return (u64&)value;
|
||||
return static_cast<T>(cast_ppu_gpr<underlying_type>::from_gpr(reg));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cast_ppu_gpr<s8, 1>
|
||||
struct cast_ppu_gpr<u8, false>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const u8& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
__forceinline static u8 from_gpr(const u64 reg)
|
||||
{
|
||||
return static_cast<u8>(reg);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cast_ppu_gpr<u16, false>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const u16& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
__forceinline static u16 from_gpr(const u64 reg)
|
||||
{
|
||||
return static_cast<u16>(reg);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cast_ppu_gpr<u32, false>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const u32& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
__forceinline static u32 from_gpr(const u64 reg)
|
||||
{
|
||||
return static_cast<u32>(reg);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cast_ppu_gpr<u64, false>
|
||||
{
|
||||
__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<s8, false>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const s8& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
__forceinline static s8 from_gpr(const u64 reg)
|
||||
{
|
||||
return static_cast<s8>(reg);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cast_ppu_gpr<s16, 2>
|
||||
struct cast_ppu_gpr<s16, false>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const s16& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
__forceinline static s16 from_gpr(const u64 reg)
|
||||
{
|
||||
return static_cast<s16>(reg);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cast_ppu_gpr<s32, 4>
|
||||
struct cast_ppu_gpr<s32, false>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const s32& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
__forceinline static s32 from_gpr(const u64 reg)
|
||||
{
|
||||
return static_cast<s32>(reg);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cast_ppu_gpr<s64, 8>
|
||||
struct cast_ppu_gpr<s64, false>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const s64& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
__forceinline static s64 from_gpr(const u64 reg)
|
||||
{
|
||||
return static_cast<s64>(reg);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cast_ppu_gpr<bool, false>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const bool& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
__forceinline static bool from_gpr(const u64 reg)
|
||||
{
|
||||
return (bool&)reg;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
__forceinline static u64 cast_to_ppu_gpr(const T& value)
|
||||
__forceinline u64 cast_to_ppu_gpr(const T& value)
|
||||
{
|
||||
return cast_ppu_gpr<T>::to_gpr(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__forceinline T cast_from_ppu_gpr(const u64 reg)
|
||||
{
|
||||
return cast_ppu_gpr<T>::from_gpr(reg);
|
||||
}
|
||||
|
|
|
@ -535,3 +535,22 @@ namespace fmt
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
// external specializations for PPU GPR (SC_FUNC.h, CB_FUNC.h)
|
||||
|
||||
template<typename T, bool is_enum>
|
||||
struct cast_ppu_gpr;
|
||||
|
||||
template<typename T, int lvl, typename AT>
|
||||
struct cast_ppu_gpr<vm::ps3::ptr<T, lvl, AT>, false>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const vm::ps3::ptr<T, lvl, AT>& value)
|
||||
{
|
||||
return value.addr();
|
||||
}
|
||||
|
||||
__forceinline static vm::ps3::ptr<T, lvl, AT> from_gpr(const u64 reg)
|
||||
{
|
||||
return vm::ps3::ptr<T, lvl, AT>::make(cast_ppu_gpr<AT>::from_gpr(reg));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -147,3 +147,22 @@ namespace fmt
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
// external specializations for PPU GPR (SC_FUNC.h, CB_FUNC.h)
|
||||
|
||||
template<typename T, bool is_enum>
|
||||
struct cast_ppu_gpr;
|
||||
|
||||
template<typename T, typename AT>
|
||||
struct cast_ppu_gpr<vm::ps3::ref<T, AT>, false>
|
||||
{
|
||||
__forceinline static u64 to_gpr(const vm::ps3::ref<T, AT>& value)
|
||||
{
|
||||
return value.addr();
|
||||
}
|
||||
|
||||
__forceinline static vm::ps3::ref<T, AT> from_gpr(const u64 reg)
|
||||
{
|
||||
return vm::ps3::ref<T, AT>::make(cast_ppu_gpr<AT>::from_gpr(reg));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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<T>(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<T>(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<T>(CPU.FPR[1]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace detail
|
|||
|
||||
static __forceinline T func(PPUThread& CPU)
|
||||
{
|
||||
return (T&)CPU.GPR[g_count + 2];
|
||||
return cast_from_ppu_gpr<T>(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<T>(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<T>(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<T>(result);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue