cast_to_ppu_gpr(), cast_from_ppu_gpr() updated

This commit is contained in:
Nekotekina 2015-01-19 17:16:31 +03:00
parent 3428499492
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);
};
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);
}

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)
{
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]);
}
};

View file

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