cast_to_ppu_gpr(), cast_from_ppu_gpr() updated

This commit is contained in:
Nekotekina 2015-01-19 17:16:31 +03:00
commit f3c9143a81
5 changed files with 153 additions and 50 deletions

View file

@ -831,93 +831,158 @@ public:
ppu_thread& gpr(uint index, u64 value); 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 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) __forceinline static u64 to_gpr(const T& value)
{ {
u64 result = 0; return cast_ppu_gpr<underlying_type>::to_gpr(static_cast<underlying_type>(value));
(T&)result = value;
return result;
} }
};
template<typename T> __forceinline static T from_gpr(const u64 reg)
struct cast_ppu_gpr<T, 1>
{
__forceinline static u64 to_gpr(const T& value)
{ {
return (u8&)value; return static_cast<T>(cast_ppu_gpr<underlying_type>::from_gpr(reg));
}
};
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;
} }
}; };
template<> 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) __forceinline static u64 to_gpr(const s8& value)
{ {
return value; return value;
} }
__forceinline static s8 from_gpr(const u64 reg)
{
return static_cast<s8>(reg);
}
}; };
template<> template<>
struct cast_ppu_gpr<s16, 2> struct cast_ppu_gpr<s16, false>
{ {
__forceinline static u64 to_gpr(const s16& value) __forceinline static u64 to_gpr(const s16& value)
{ {
return value; return value;
} }
__forceinline static s16 from_gpr(const u64 reg)
{
return static_cast<s16>(reg);
}
}; };
template<> template<>
struct cast_ppu_gpr<s32, 4> struct cast_ppu_gpr<s32, false>
{ {
__forceinline static u64 to_gpr(const s32& value) __forceinline static u64 to_gpr(const s32& value)
{ {
return value; return value;
} }
__forceinline static s32 from_gpr(const u64 reg)
{
return static_cast<s32>(reg);
}
}; };
template<> template<>
struct cast_ppu_gpr<s64, 8> struct cast_ppu_gpr<s64, false>
{ {
__forceinline static u64 to_gpr(const s64& value) __forceinline static u64 to_gpr(const s64& value)
{ {
return 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> 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); 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);
}

View file

@ -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));
}
};

View file

@ -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));
}
};

View file

@ -37,7 +37,7 @@ namespace cb_detail
__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; CPU.FPR[f_count] = static_cast<T>(arg);
} }
}; };
@ -101,7 +101,7 @@ namespace cb_detail
__forceinline static T get_value(const PPUThread& CPU) __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) __forceinline static T get_value(const PPUThread& CPU)
{ {
return (T)CPU.FPR[1]; return static_cast<T>(CPU.FPR[1]);
} }
}; };

View file

@ -28,7 +28,7 @@ namespace detail
static __forceinline T func(PPUThread& CPU) 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) 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 // 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)); 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) static __forceinline void func(PPUThread& CPU, const T& result)
{ {
CPU.FPR[1] = result; CPU.FPR[1] = static_cast<T>(result);
} }
}; };