From 59f1077a3675075e9d405ca97183a17c713e1540 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 14 Sep 2015 19:32:35 +0300 Subject: [PATCH] Cleanup, be_t fixed Some functions renamed: get_ps3_function_name execute_syscall_by_index --- Utilities/BEType.h | 756 ++++++++++------------ rpcs3/Emu/Cell/PPUInterpreter.cpp | 6 +- rpcs3/Emu/Cell/PPUInterpreter.h | 109 ++-- rpcs3/Emu/Cell/PPULLVMRecompiler.cpp | 1 + rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp | 11 +- rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp | 4 +- rpcs3/Emu/Cell/PPUThread.cpp | 18 +- rpcs3/Emu/Cell/PPUThread.h | 17 + rpcs3/Emu/SysCalls/FuncList.cpp | 2 +- rpcs3/Emu/SysCalls/Modules.cpp | 46 +- rpcs3/Emu/SysCalls/Modules.h | 20 +- rpcs3/Emu/SysCalls/SysCalls.cpp | 16 +- rpcs3/Emu/SysCalls/SysCalls.h | 10 +- rpcs3/Emu/SysCalls/lv2/sys_prx.cpp | 6 +- rpcs3/Loader/ELF64.cpp | 18 +- 15 files changed, 476 insertions(+), 564 deletions(-) diff --git a/Utilities/BEType.h b/Utilities/BEType.h index e96c6f8499..b9e1d542a0 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -8,97 +8,74 @@ #define IS_LE_MACHINE // only draft +template class masked_array_t // array type accessed as (index ^ M) +{ + T m_data[N]; + +public: + T& operator [](std::size_t index) + { + return m_data[index ^ M]; + } + + const T& operator [](std::size_t index) const + { + return m_data[index ^ M]; + } + + T& at(std::size_t index) + { + return (index ^ M) < N ? m_data[index ^ M] : throw std::out_of_range("Masked array"); + } + + const T& at(std::size_t index) const + { + return (index ^ M) < N ? m_data[index ^ M] : throw std::out_of_range("Masked array"); + } +}; + union v128 { - u64 _u64[2]; - s64 _s64[2]; +#ifdef IS_LE_MACHINE + template using normal_array_t = masked_array_t; + template using reversed_array_t = masked_array_t; +#else + template using normal_array_t = masked_array_t; + template using reversed_array_t = masked_array_t; +#endif - class u64_reversed_array_2 - { - u64 data[2]; + normal_array_t _u64; + normal_array_t _s64; + reversed_array_t u64r; + reversed_array_t s64r; - public: - u64& operator [] (s32 index) - { - return data[1 - index]; - } + normal_array_t _u32; + normal_array_t _s32; + reversed_array_t u32r; + reversed_array_t s32r; - const u64& operator [] (s32 index) const - { - return data[1 - index]; - } + normal_array_t _u16; + normal_array_t _s16; + reversed_array_t u16r; + reversed_array_t s16r; - } u64r; + normal_array_t _u8; + normal_array_t _s8; + reversed_array_t u8r; + reversed_array_t s8r; - u32 _u32[4]; - s32 _s32[4]; + normal_array_t _f; + normal_array_t _d; + reversed_array_t fr; + reversed_array_t dr; - class u32_reversed_array_4 - { - u32 data[4]; - - public: - u32& operator [] (s32 index) - { - return data[3 - index]; - } - - const u32& operator [] (s32 index) const - { - return data[3 - index]; - } - - } u32r; - - u16 _u16[8]; - s16 _s16[8]; - - class u16_reversed_array_8 - { - u16 data[8]; - - public: - u16& operator [] (s32 index) - { - return data[7 - index]; - } - - const u16& operator [] (s32 index) const - { - return data[7 - index]; - } - - } u16r; - - u8 _u8[16]; - s8 _s8[16]; - - class u8_reversed_array_16 - { - u8 data[16]; - - public: - u8& operator [] (s32 index) - { - return data[15 - index]; - } - - const u8& operator [] (s32 index) const - { - return data[15 - index]; - } - - } u8r; - - float _f[4]; - double _d[2]; __m128 vf; __m128i vi; __m128d vd; class bit_array_128 { - u64 data[2]; + u64 m_data[2]; public: class bit_element @@ -113,12 +90,12 @@ union v128 { } - force_inline operator bool() const + inline operator bool() const { return (data & mask) != 0; } - force_inline bit_element& operator = (const bool right) + inline bit_element& operator =(const bool right) { if (right) { @@ -131,7 +108,7 @@ union v128 return *this; } - force_inline bit_element& operator = (const bit_element& right) + inline bit_element& operator =(const bit_element& right) { if (right) { @@ -146,30 +123,40 @@ union v128 }; // Index 0 returns the MSB and index 127 returns the LSB - bit_element operator [] (u32 index) + bit_element operator [](u32 index) { - assert(index < 128); - #ifdef IS_LE_MACHINE - return bit_element(data[1 - (index >> 6)], 0x8000000000000000ull >> (index & 0x3F)); + return bit_element(m_data[1 - (index >> 6)], 0x8000000000000000ull >> (index & 0x3F)); #else - return bit_element(data[index >> 6], 0x8000000000000000ull >> (index & 0x3F)); + return bit_element(m_data[index >> 6], 0x8000000000000000ull >> (index & 0x3F)); #endif } // Index 0 returns the MSB and index 127 returns the LSB - const bool operator [] (u32 index) const + bool operator [](u32 index) const { - assert(index < 128); - #ifdef IS_LE_MACHINE - return (data[1 - (index >> 6)] & (0x8000000000000000ull >> (index & 0x3F))) != 0; + return (m_data[1 - (index >> 6)] & (0x8000000000000000ull >> (index & 0x3F))) != 0; #else - return (data[index >> 6] & (0x8000000000000000ull >> (index & 0x3F))) != 0; + return (m_data[index >> 6] & (0x8000000000000000ull >> (index & 0x3F))) != 0; #endif } - } _bit; + bit_element at(u32 index) + { + if (index >= 128) throw std::out_of_range("Bit element"); + + return operator[](index); + } + + bool at(u32 index) const + { + if (index >= 128) throw std::out_of_range("Bit element"); + + return operator[](index); + } + } + _bit; static v128 from64(u64 _0, u64 _1 = 0) { @@ -248,117 +235,118 @@ union v128 return ret; } - static force_inline v128 add8(const v128& left, const v128& right) + static inline v128 add8(const v128& left, const v128& right) { return fromV(_mm_add_epi8(left.vi, right.vi)); } - static force_inline v128 add16(const v128& left, const v128& right) + static inline v128 add16(const v128& left, const v128& right) { return fromV(_mm_add_epi16(left.vi, right.vi)); } - static force_inline v128 add32(const v128& left, const v128& right) + static inline v128 add32(const v128& left, const v128& right) { return fromV(_mm_add_epi32(left.vi, right.vi)); } - static force_inline v128 addfs(const v128& left, const v128& right) + static inline v128 addfs(const v128& left, const v128& right) { return fromF(_mm_add_ps(left.vf, right.vf)); } - static force_inline v128 addfd(const v128& left, const v128& right) + static inline v128 addfd(const v128& left, const v128& right) { return fromD(_mm_add_pd(left.vd, right.vd)); } - static force_inline v128 sub8(const v128& left, const v128& right) + static inline v128 sub8(const v128& left, const v128& right) { return fromV(_mm_sub_epi8(left.vi, right.vi)); } - static force_inline v128 sub16(const v128& left, const v128& right) + static inline v128 sub16(const v128& left, const v128& right) { return fromV(_mm_sub_epi16(left.vi, right.vi)); } - static force_inline v128 sub32(const v128& left, const v128& right) + static inline v128 sub32(const v128& left, const v128& right) { return fromV(_mm_sub_epi32(left.vi, right.vi)); } - static force_inline v128 subfs(const v128& left, const v128& right) + static inline v128 subfs(const v128& left, const v128& right) { return fromF(_mm_sub_ps(left.vf, right.vf)); } - static force_inline v128 subfd(const v128& left, const v128& right) + static inline v128 subfd(const v128& left, const v128& right) { return fromD(_mm_sub_pd(left.vd, right.vd)); } - static force_inline v128 maxu8(const v128& left, const v128& right) + static inline v128 maxu8(const v128& left, const v128& right) { return fromV(_mm_max_epu8(left.vi, right.vi)); } - static force_inline v128 minu8(const v128& left, const v128& right) + static inline v128 minu8(const v128& left, const v128& right) { return fromV(_mm_min_epu8(left.vi, right.vi)); } - static force_inline v128 eq8(const v128& left, const v128& right) + static inline v128 eq8(const v128& left, const v128& right) { return fromV(_mm_cmpeq_epi8(left.vi, right.vi)); } - static force_inline v128 eq16(const v128& left, const v128& right) + static inline v128 eq16(const v128& left, const v128& right) { return fromV(_mm_cmpeq_epi16(left.vi, right.vi)); } - static force_inline v128 eq32(const v128& left, const v128& right) + static inline v128 eq32(const v128& left, const v128& right) { return fromV(_mm_cmpeq_epi32(left.vi, right.vi)); } - bool operator == (const v128& right) const + bool operator ==(const v128& right) const { - return (_u64[0] == right._u64[0]) && (_u64[1] == right._u64[1]); + return _u64[0] == right._u64[0] && _u64[1] == right._u64[1]; } - bool operator != (const v128& right) const + bool operator !=(const v128& right) const { - return (_u64[0] != right._u64[0]) || (_u64[1] != right._u64[1]); + return _u64[0] != right._u64[0] || _u64[1] != right._u64[1]; } - force_inline bool is_any_1() const // check if any bit is 1 + inline bool is_any_1() const // check if any bit is 1 { return _u64[0] || _u64[1]; } - force_inline bool is_any_0() const // check if any bit is 0 + inline bool is_any_0() const // check if any bit is 0 { return ~_u64[0] || ~_u64[1]; } // result = (~left) & (right) - static force_inline v128 andnot(const v128& left, const v128& right) + static inline v128 andnot(const v128& left, const v128& right) { return fromV(_mm_andnot_si128(left.vi, right.vi)); } void clear() { - _u64[1] = _u64[0] = 0; + _u64[0] = 0; + _u64[1] = 0; } std::string to_hex() const; std::string to_xyzw() const; - static force_inline v128 byteswap(const v128 val) + static inline v128 byteswap(const v128 val) { return fromV(_mm_shuffle_epi8(val.vi, _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15))); } @@ -386,293 +374,301 @@ inline v128 operator ~(const v128& other) return v128::from64(~other._u64[0], ~other._u64[1]); } -template struct se_t; - -template struct se_t +template struct se_storage { - static force_inline u16 to(const T& src) - { - return _byteswap_ushort((u16&)src); - } - - static force_inline T from(const u16 src) - { - const u16 res = _byteswap_ushort(src); - return (T&)res; - } + static_assert(!Size, "Bad se_storage<> type"); }; -template struct se_t -{ - static force_inline u32 to(const T& src) - { - return _byteswap_ulong((u32&)src); - } - - static force_inline T from(const u32 src) - { - const u32 res = _byteswap_ulong(src); - return (T&)res; - } -}; - -template struct se_t -{ - static force_inline u64 to(const T& src) - { - return _byteswap_uint64((u64&)src); - } - - static force_inline T from(const u64 src) - { - const u64 res = _byteswap_uint64(src); - return (T&)res; - } -}; - -template struct se_t -{ - static force_inline v128 to(const T& src) - { - return v128::byteswap((v128&)src); - } - - static force_inline T from(const v128& src) - { - const v128 res = v128::byteswap(src); - return (T&)res; - } -}; - -template struct const_se_t; - -template struct const_se_t -{ - static const u16 value = - ((_value >> 8) & 0x00ff) | - ((_value << 8) & 0xff00); -}; - -template struct const_se_t -{ - static const u32 value = - ((_value >> 24) & 0x000000ff) | - ((_value >> 8) & 0x0000ff00) | - ((_value << 8) & 0x00ff0000) | - ((_value << 24) & 0xff000000); -}; - -template struct const_se_t -{ - static const u64 value = - ((_value >> 56) & 0x00000000000000ff) | - ((_value >> 40) & 0x000000000000ff00) | - ((_value >> 24) & 0x0000000000ff0000) | - ((_value >> 8) & 0x00000000ff000000) | - ((_value << 8) & 0x000000ff00000000) | - ((_value << 24) & 0x0000ff0000000000) | - ((_value << 40) & 0x00ff000000000000) | - ((_value << 56) & 0xff00000000000000); -}; - -template struct be_storage -{ - static_assert(!size, "Bad be_storage_t<> type"); -}; - -template struct be_storage +template struct se_storage { using type = u16; + + static inline u16 to(const T& src) + { + return _byteswap_ushort(reinterpret_cast(src)); + } + + static inline T from(u16 src) + { + const u16 result = _byteswap_ushort(src); + return reinterpret_cast(result); + } }; -template struct be_storage +template struct se_storage { using type = u32; + + static inline u32 to(const T& src) + { + return _byteswap_ulong(reinterpret_cast(src)); + } + + static inline T from(u32 src) + { + const u32 result = _byteswap_ulong(src); + return reinterpret_cast(result); + } }; -template struct be_storage +template struct se_storage { using type = u64; + + static inline u64 to(const T& src) + { + return _byteswap_uint64(reinterpret_cast(src)); + } + + static inline T from(u64 src) + { + const u64 result = _byteswap_uint64(src); + return reinterpret_cast(result); + } }; -template struct be_storage +template struct se_storage { using type = v128; + + static inline v128 to(const T& src) + { + return v128::byteswap(reinterpret_cast(src)); + } + + static inline T from(const v128& src) + { + const v128 result = v128::byteswap(src); + return reinterpret_cast(result); + } }; -template using be_storage_t = typename be_storage::type; +template using se_storage_t = typename se_storage::type; -template class be_t +template struct se_convert { - // TODO (complicated cases like int-float conversions are not handled correctly) - template - struct _convert - { - static force_inline be_t& func(Tfrom& be_value) - { - Tto res = be_value; - return (be_t&)res; - } - }; + using type_from = std::remove_cv_t; + using type_to = std::remove_cv_t; + using stype_from = se_storage_t>; + using stype_to = se_storage_t>; + using storage_from = se_storage>; + using storage_to = se_storage>; - template - struct _convert + static inline std::enable_if_t::value, stype_to> convert(const stype_from& data) { - static force_inline be_t& func(Tfrom& be_value) - { - Tto res = se_t::func(se_t::func(be_value)); - return (be_t&)res; - } - }; + return data; + } - template - struct _convert + static inline stype_to convert(const stype_from& data, ...) { - static force_inline be_t& func(Tfrom& be_value) - { - Tto res = be_value >> ((sizeof(Tfrom) - sizeof(Tto)) * 8); - return (be_t&)res; - } - }; + return storage_to::to(storage_from::from(data)); + } +}; + +template class se_t +{ + using type = std::remove_cv_t; + using stype = se_storage_t>; + using storage = se_storage>; + + stype m_data; + + static_assert(!std::is_class::value || std::is_same::value, "se_t<> error: invalid type (class or structure)"); + static_assert(!std::is_union::value || std::is_same::value || std::is_same::value, "se_t<> error: invalid type (union)"); + static_assert(!std::is_pointer::value, "se_t<> error: invalid type (pointer)"); + static_assert(!std::is_reference::value, "se_t<> error: invalid type (reference)"); + static_assert(!std::is_array::value, "se_t<> error: invalid type (array)"); + static_assert(!std::is_enum::value, "se_t<> error: invalid type (enumeration), use integral type instead"); + static_assert(alignof(type) == alignof(stype), "se_t<> error: unexpected alignment"); public: - using type = std::remove_cv_t; - using stype = be_storage_t>; + se_t() = default; -#ifdef IS_LE_MACHINE - stype m_data; // don't access directly -#else - type m_data; // don't access directly -#endif + se_t(const se_t&) = default; - static_assert(!std::is_class::value || std::is_same::value, "be_t<> error: invalid type (class or structure)"); - static_assert(!std::is_union::value || std::is_same::value || std::is_same::value, "be_t<> error: invalid type (union)"); - static_assert(!std::is_pointer::value, "be_t<> error: invalid type (pointer)"); - static_assert(!std::is_reference::value, "be_t<> error: invalid type (reference)"); - static_assert(!std::is_array::value, "be_t<> error: invalid type (array)"); - static_assert(!std::is_enum::value, "be_t<> error: invalid type (enumeration), use integral type instead"); - static_assert(alignof(type) == alignof(stype), "be_t<> error: unexpected alignment"); - - be_t() = default; - - be_t(const be_t&) = default; - - force_inline be_t(const type& value) -#ifdef IS_LE_MACHINE - : m_data(se_t::to(value)) -#else - : m_data(value) -#endif + inline se_t(const type& value) + : m_data(storage::to(value)) { } - // get value in current machine byte ordering - force_inline type value() const + inline type value() const { -#ifdef IS_LE_MACHINE - return se_t::from(m_data); -#else - return m_data; -#endif + return storage::from(m_data); } - // get underlying data without any byte order manipulation - const stype& data() const + inline const stype& data() const { -#ifdef IS_LE_MACHINE return m_data; -#else - return reinterpret_cast(m_data); -#endif } - be_t& operator =(const be_t&) = default; + se_t& operator =(const se_t&) = default; - template std::enable_if_t::value, be_t&> operator =(const CT& value) + template std::enable_if_t::value, se_t&> operator =(const CT& value) { -#ifdef IS_LE_MACHINE - m_data = se_t::to(value); -#else - m_data = value; -#endif - - return *this; + return m_data = storage::to(value), *this; } - //template::value>> operator CT() const - //{ - // return value(); - //} - operator type() const { return value(); } - - // conversion to another be_t type - //template operator be_t() const - //{ - // return value(); - // //return _convert sizeof(T)) ? 1 : (sizeof(T1) < sizeof(T) ? 2 : 0))>::func(m_data); - //} - - template be_t& operator +=(const T1& right) { return *this = value() + right; } - template be_t& operator -=(const T1& right) { return *this = value() - right; } - template be_t& operator *=(const T1& right) { return *this = value() * right; } - template be_t& operator /=(const T1& right) { return *this = value() / right; } - template be_t& operator %=(const T1& right) { return *this = value() % right; } - - template be_t& operator <<=(const T1& right) { return *this = value() << right; } - template be_t& operator >>=(const T1& right) { return *this = value() >> right; } - - template be_t& operator &=(const T1& right) { return m_data &= be_t(right).data(), *this; } - template be_t& operator |=(const T1& right) { return m_data |= be_t(right).data(), *this; } - template be_t& operator ^=(const T1& right) { return m_data ^= be_t(right).data(), *this; } - - be_t operator ++(int) { be_t res = *this; *this += 1; return res; } - be_t operator --(int) { be_t res = *this; *this -= 1; return res; } - be_t& operator ++() { *this += 1; return *this; } - be_t& operator --() { *this -= 1; return *this; } }; -template inline std::enable_if_t::value && std::is_integral::value, bool> operator ==(const be_t& left, const be_t& right) +template class se_t +{ + using type = std::remove_cv_t; + using stype = se_storage_t>; + using storage = se_storage>; + + type m_data; + + static_assert(!std::is_class::value || std::is_same::value, "se_t<> error: invalid type (class or structure)"); + static_assert(!std::is_union::value || std::is_same::value || std::is_same::value, "se_t<> error: invalid type (union)"); + static_assert(!std::is_pointer::value, "se_t<> error: invalid type (pointer)"); + static_assert(!std::is_reference::value, "se_t<> error: invalid type (reference)"); + static_assert(!std::is_array::value, "se_t<> error: invalid type (array)"); + static_assert(!std::is_enum::value, "se_t<> error: invalid type (enumeration), use integral type instead"); + static_assert(alignof(type) == alignof(stype), "se_t<> error: unexpected alignment"); + +public: + se_t() = default; + + se_t(const se_t&) = default; + + inline se_t(const type& value) + : m_data(value) + { + } + + inline type value() const + { + return m_data; + } + + inline const stype& data() const + { + return reinterpret_cast(m_data); + } + + se_t& operator =(const se_t& value) = default; + + template std::enable_if_t::value, se_t&> operator =(const CT& value) + { + return m_data = value, *this; + } + + operator type() const + { + return value(); + } +}; + +template inline std::enable_if_t::value && std::is_integral::value, bool> operator ==(const se_t& left, const se_t& right) { return left.data() == right.data(); } -template inline std::enable_if_t::value && std::is_integral::value, bool> operator !=(const be_t& left, const be_t& right) +template inline std::enable_if_t::value && std::is_integral::value, bool> operator !=(const se_t& left, const se_t& right) { return left.data() != right.data(); } -template inline std::enable_if_t::value && std::is_integral::value, be_t> operator &(const be_t& left, const be_t& right) +template inline se_t& operator +=(se_t& left, const T1& right) { - be_t result; - result.m_data = left.data() & right.data(); + auto value = left.value(); + return left = (value += right); +} + +template inline se_t& operator -=(se_t& left, const T1& right) +{ + auto value = left.value(); + return left = (value -= right); +} + +template inline se_t& operator *=(se_t& left, const T1& right) +{ + auto value = left.value(); + return left = (value *= right); +} + +template inline se_t& operator /=(se_t& left, const T1& right) +{ + auto value = left.value(); + return left = (value /= right); +} + +template inline se_t& operator %=(se_t& left, const T1& right) +{ + auto value = left.value(); + return left = (value %= right); +} + +template inline se_t& operator <<=(se_t& left, const T1& right) +{ + auto value = left.value(); + return left = (value <<= right); +} + +template inline se_t& operator >>=(se_t& left, const T1& right) +{ + auto value = left.value(); + return left = (value >>= right); +} + +template inline se_t& operator &=(se_t& left, const T1& right) +{ + auto value = left.value(); + return left = (value &= right); +} + +template inline se_t& operator |=(se_t& left, const T1& right) +{ + auto value = left.value(); + return left = (value |= right); +} + +template inline se_t& operator ^=(se_t& left, const T1& right) +{ + auto value = left.value(); + return left = (value ^= right); +} + +template inline se_t operator ++(se_t& left, int) +{ + auto value = left.value(); + auto result = value++; + left = value; return result; } -template inline std::enable_if_t::value && std::is_integral::value, be_t> operator |(const be_t& left, const be_t& right) +template inline se_t operator --(se_t& left, int) { - be_t result; - result.m_data = left.data() | right.data(); + auto value = left.value(); + auto result = value--; + left = value; return result; } -template inline std::enable_if_t::value && std::is_integral::value, be_t> operator ^(const be_t& left, const be_t& right) +template inline se_t& operator ++(se_t& right) { - be_t result; - result.m_data = left.data() ^ right.data(); - return result; + auto value = right.value(); + return right = ++value; } -template inline std::enable_if_t::value, be_t> operator ~(const be_t& arg) +template inline se_t& operator --(se_t& right) { - be_t result; - result.m_data = ~arg.data(); - return result; + auto value = right.value(); + return right = --value; } +#ifdef IS_LE_MACHINE +template using be_t = se_t; +template using le_t = se_t; +#else +template using be_t = se_t; +template using le_t = se_t; +#endif + template struct is_be_t : public std::integral_constant { }; @@ -698,15 +694,13 @@ template struct to_be // be_t if possible, T otherwise template using to_be_t = typename to_be::type; -template struct to_be +template struct to_be // move const qualifier { - // move const qualifier using type = const to_be_t; }; -template struct to_be +template struct to_be // move volatile qualifier { - // move volatile qualifier using type = volatile to_be_t; }; @@ -716,79 +710,6 @@ template<> struct to_be { using type = char; }; template<> struct to_be { using type = u8; }; template<> struct to_be { using type = s8; }; -template class le_t -{ -public: - using type = std::remove_cv_t; - using stype = be_storage_t>; - - type m_data; // don't access directly - - static_assert(!std::is_class::value || std::is_same::value, "le_t<> error: invalid type (class or structure)"); - static_assert(!std::is_union::value || std::is_same::value || std::is_same::value, "le_t<> error: invalid type (union)"); - static_assert(!std::is_pointer::value, "le_t<> error: invalid type (pointer)"); - static_assert(!std::is_reference::value, "le_t<> error: invalid type (reference)"); - static_assert(!std::is_array::value, "le_t<> error: invalid type (array)"); - static_assert(!std::is_enum::value, "le_t<> error: invalid type (enumeration), use integral type instead"); - static_assert(alignof(type) == alignof(stype), "le_t<> error: unexpected alignment"); - - le_t() = default; - - le_t(const le_t&) = default; - - le_t(const type& value) - : m_data(value) - { - } - - type value() const - { - return m_data; - } - - const stype& data() const - { - return reinterpret_cast(m_data); - } - - le_t& operator =(const le_t& value) = default; - - template std::enable_if_t::value, le_t&> operator =(const CT& value) - { - m_data = value; - return *this; - } - - operator type() const - { - return value(); - } - - // conversion to another le_t type - //template operator le_t() const - //{ - // return value(); - //} - - template le_t& operator +=(const T1& right) { return *this = value() + right; } - template le_t& operator -=(const T1& right) { return *this = value() - right; } - template le_t& operator *=(const T1& right) { return *this = value() * right; } - template le_t& operator /=(const T1& right) { return *this = value() / right; } - template le_t& operator %=(const T1& right) { return *this = value() % right; } - - template le_t& operator <<=(const T1& right) { return *this = value() << right; } - template le_t& operator >>=(const T1& right) { return *this = value() >> right; } - - template le_t& operator &=(const T1& right) { return m_data &= le_t(right).data(), *this; } - template le_t& operator |=(const T1& right) { return m_data |= le_t(right).data(), *this; } - template le_t& operator ^=(const T1& right) { return m_data ^= le_t(right).data(), *this; } - - le_t operator ++(int) { le_t res = *this; *this += 1; return res; } - le_t operator --(int) { le_t res = *this; *this -= 1; return res; } - le_t& operator ++() { *this += 1; return *this; } - le_t& operator --() { *this -= 1; return *this; } -}; - template struct is_le_t : public std::integral_constant { }; @@ -813,15 +734,13 @@ template struct to_le // le_t if possible, T otherwise template using to_le_t = typename to_le::type; -template struct to_le +template struct to_le // move const qualifier { - // move const qualifier using type = const to_le_t; }; -template struct to_le +template struct to_le // move volatile qualifier { - // move volatile qualifier using type = volatile to_le_t; }; @@ -837,12 +756,7 @@ template struct to_ne using type = T; }; -template struct to_ne> -{ - using type = T; -}; - -template struct to_ne> +template struct to_ne> { using type = T; }; @@ -850,14 +764,12 @@ template struct to_ne> // restore native endianness for T: returns T for be_t or le_t, T otherwise template using to_ne_t = typename to_ne::type; -template struct to_ne +template struct to_ne // move const qualifier { - // move const qualifier using type = const to_ne_t; }; -template struct to_ne +template struct to_ne // move volatile qualifier { - // move volatile qualifier using type = volatile to_ne_t; }; diff --git a/rpcs3/Emu/Cell/PPUInterpreter.cpp b/rpcs3/Emu/Cell/PPUInterpreter.cpp index d2e2d15524..5d94b04a3c 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/PPUInterpreter.cpp @@ -970,8 +970,8 @@ void ppu_interpreter::VSLB(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::VSLDOI(PPUThread& CPU, ppu_opcode_t op) { u8 tmpSRC[32]; - memcpy(tmpSRC, CPU.VPR[op.vb]._u8, 16); - memcpy(tmpSRC + 16, CPU.VPR[op.va]._u8, 16); + std::memcpy(tmpSRC, CPU.VPR + op.vb, 16); + std::memcpy(tmpSRC + 16, CPU.VPR + op.va, 16); for (uint b = 0; b<16; b++) { @@ -1475,7 +1475,7 @@ void ppu_interpreter::SC(PPUThread& CPU, ppu_opcode_t op) { switch (op.lev) { - case 0x0: SysCalls::DoSyscall(CPU, CPU.GPR[11]); break; + case 0x0: execute_syscall_by_index(CPU, CPU.GPR[11]); break; case 0x3: CPU.fast_stop(); break; default: throw EXCEPTION(""); } diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index 7e9ebc0419..1692fb76e9 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -1,9 +1,6 @@ #pragma once #include "Emu/Cell/PPUOpcodes.h" -#include "Emu/SysCalls/SysCalls.h" -#include "rpcs3/Ini.h" -#include "Emu/SysCalls/Modules.h" #include "Emu/Memory/Memory.h" #include @@ -16,7 +13,7 @@ #include -extern u64 rotate_mask[64][64]; // defined in PPUThread.cpp, static didn't work correctly in GCC 4.9 for some reason +extern u64 rotate_mask[64][64]; // defined in PPUThread.cpp extern u64 get_timebased_time(); inline void InitRotateMask() @@ -1327,8 +1324,8 @@ private: void VPERM(u32 vd, u32 va, u32 vb, u32 vc) { u8 tmpSRC[32]; - memcpy(tmpSRC, CPU.VPR[vb]._u8, 16); - memcpy(tmpSRC + 16, CPU.VPR[va]._u8, 16); + std::memcpy(tmpSRC, CPU.VPR + vb, 16); + std::memcpy(tmpSRC + 16, CPU.VPR + va, 16); for (uint b = 0; b < 16; b++) { @@ -1703,8 +1700,8 @@ private: void VSLDOI(u32 vd, u32 va, u32 vb, u32 sh) { u8 tmpSRC[32]; - memcpy(tmpSRC, CPU.VPR[vb]._u8, 16); - memcpy(tmpSRC + 16, CPU.VPR[va]._u8, 16); + std::memcpy(tmpSRC, CPU.VPR + vb, 16); + std::memcpy(tmpSRC + 16, CPU.VPR + va, 16); for(uint b=0; b<16; b++) { @@ -2232,13 +2229,17 @@ private: } void HACK(u32 index) { + extern void execute_ppu_func_by_index(PPUThread& ppu, u32 index); + execute_ppu_func_by_index(CPU, index); } void SC(u32 lev) { + extern void execute_syscall_by_index(PPUThread& ppu, u64 code); + switch (lev) { - case 0x0: SysCalls::DoSyscall(CPU, CPU.GPR[11]); break; + case 0x0: execute_syscall_by_index(CPU, CPU.GPR[11]); break; case 0x1: throw EXCEPTION("HyperCall LV1"); case 0x3: CPU.fast_stop(); break; default: throw EXCEPTION("Unknown level (0x%x)", lev); @@ -2487,12 +2488,12 @@ private: void LDX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::read64(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read64(VM_CAST(addr)); } void LWZX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::read32(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read32(VM_CAST(addr)); } void SLW(u32 ra, u32 rs, u32 rb, u32 rc) { @@ -2564,7 +2565,7 @@ private: void LVEHX(u32 vd, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~1ULL; - CPU.VPR[vd]._u16[7 - ((addr >> 1) & 0x7)] = vm::read16(VM_CAST(addr)); + CPU.VPR[vd]._u16[7 - ((addr >> 1) & 0x7)] = vm::ps3::read16(VM_CAST(addr)); // check LVEWX comments } void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) @@ -2578,7 +2579,7 @@ private: void LDUX(u32 rd, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - CPU.GPR[rd] = vm::read64(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read64(VM_CAST(addr)); CPU.GPR[ra] = addr; } void DCBST(u32 ra, u32 rb) @@ -2587,7 +2588,7 @@ private: void LWZUX(u32 rd, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - CPU.GPR[rd] = vm::read32(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read32(VM_CAST(addr)); CPU.GPR[ra] = addr; } void CNTLZD(u32 ra, u32 rs, u32 rc) @@ -2613,7 +2614,7 @@ private: void LVEWX(u32 vd, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~3ULL; - CPU.VPR[vd]._u32[3 - ((addr >> 2) & 0x3)] = vm::read32(VM_CAST(addr)); + CPU.VPR[vd]._u32[3 - ((addr >> 2) & 0x3)] = vm::ps3::read32(VM_CAST(addr)); // It's not very good idea to implement it using read128(), // because it can theoretically read RawSPU 32-bit MMIO register (read128() will fail) //CPU.VPR[vd] = vm::read128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL); @@ -2650,7 +2651,7 @@ private: void LVX(u32 vd, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfull; - CPU.VPR[vd] = vm::read128(VM_CAST(addr)); + CPU.VPR[vd] = vm::ps3::read128(VM_CAST(addr)); } void NEG(u32 rd, u32 ra, u32 oe, u32 rc) { @@ -2746,7 +2747,7 @@ private: void STDX(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::write64(VM_CAST(addr), CPU.GPR[rs]); + vm::ps3::write64(VM_CAST(addr), CPU.GPR[rs]); } void STWCX_(u32 rs, u32 ra, u32 rb) { @@ -2758,31 +2759,31 @@ private: void STWX(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); + vm::ps3::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); } void STVEHX(u32 vs, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~1ULL; const u8 eb = (addr & 0xf) >> 1; - vm::write16(VM_CAST(addr), CPU.VPR[vs]._u16[7 - eb]); + vm::ps3::write16(VM_CAST(addr), CPU.VPR[vs]._u16[7 - eb]); } void STDUX(u32 rs, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - vm::write64(VM_CAST(addr), CPU.GPR[rs]); + vm::ps3::write64(VM_CAST(addr), CPU.GPR[rs]); CPU.GPR[ra] = addr; } void STWUX(u32 rs, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - vm::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); + vm::ps3::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); CPU.GPR[ra] = addr; } void STVEWX(u32 vs, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~3ULL; const u8 eb = (addr & 0xf) >> 2; - vm::write32(VM_CAST(addr), CPU.VPR[vs]._u32[3 - eb]); + vm::ps3::write32(VM_CAST(addr), CPU.VPR[vs]._u32[3 - eb]); } void SUBFZE(u32 rd, u32 ra, u32 oe, u32 rc) { @@ -2815,7 +2816,7 @@ private: void STVX(u32 vs, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfull; - vm::write128(VM_CAST(addr), CPU.VPR[vs]); + vm::ps3::write128(VM_CAST(addr), CPU.VPR[vs]); } void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { @@ -2875,7 +2876,7 @@ private: void LHZX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::read16(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read16(VM_CAST(addr)); } void EQV(u32 ra, u32 rs, u32 rb, u32 rc) { @@ -2889,7 +2890,7 @@ private: void LHZUX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::read16(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read16(VM_CAST(addr)); CPU.GPR[ra] = addr; } void XOR(u32 ra, u32 rs, u32 rb, u32 rc) @@ -2904,7 +2905,7 @@ private: void LWAX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = (s64)(s32)vm::read32(VM_CAST(addr)); + CPU.GPR[rd] = (s64)(s32)vm::ps3::read32(VM_CAST(addr)); } void DST(u32 ra, u32 rb, u32 strm, u32 t) { @@ -2912,12 +2913,12 @@ private: void LHAX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = (s64)(s16)vm::read16(VM_CAST(addr)); + CPU.GPR[rd] = (s64)(s16)vm::ps3::read16(VM_CAST(addr)); } void LVXL(u32 vd, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfull; - CPU.VPR[vd] = vm::read128(VM_CAST(addr)); + CPU.VPR[vd] = vm::ps3::read128(VM_CAST(addr)); } void MFTB(u32 rd, u32 spr) { @@ -2934,7 +2935,7 @@ private: void LWAUX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = (s64)(s32)vm::read32(VM_CAST(addr)); + CPU.GPR[rd] = (s64)(s32)vm::ps3::read32(VM_CAST(addr)); CPU.GPR[ra] = addr; } void DSTST(u32 ra, u32 rb, u32 strm, u32 t) @@ -2943,13 +2944,13 @@ private: void LHAUX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = (s64)(s16)vm::read16(VM_CAST(addr)); + CPU.GPR[rd] = (s64)(s16)vm::ps3::read16(VM_CAST(addr)); CPU.GPR[ra] = addr; } void STHX(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); + vm::ps3::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); } void ORC(u32 ra, u32 rs, u32 rb, u32 rc) { @@ -2963,7 +2964,7 @@ private: void STHUX(u32 rs, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - vm::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); + vm::ps3::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); CPU.GPR[ra] = addr; } void OR(u32 ra, u32 rs, u32 rb, u32 rc) @@ -3023,7 +3024,7 @@ private: void STVXL(u32 vs, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfull; - vm::write128(VM_CAST(addr), CPU.VPR[vs]); + vm::ps3::write128(VM_CAST(addr), CPU.VPR[vs]); } void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { @@ -3148,7 +3149,7 @@ private: { if (N > 3) { - CPU.GPR[reg] = vm::read32(VM_CAST(addr)); + CPU.GPR[reg] = vm::ps3::read32(VM_CAST(addr)); addr += 4; N -= 4; } @@ -3216,7 +3217,7 @@ private: u32 count = CPU.XER.XER & 0x7F; for (; count >= 4; count -= 4, addr += 4, rs = (rs+1) & 31) { - vm::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); + vm::ps3::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); } if (count) { @@ -3281,7 +3282,7 @@ private: { if (N > 3) { - vm::write32(VM_CAST(addr), (u32)CPU.GPR[reg]); + vm::ps3::write32(VM_CAST(addr), (u32)CPU.GPR[reg]); addr += 4; N -= 4; } @@ -3424,7 +3425,7 @@ private: void STFIWX(u32 frs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::write32(VM_CAST(addr), (u32&)CPU.FPR[frs]); + vm::ps3::write32(VM_CAST(addr), (u32&)CPU.FPR[frs]); } void EXTSW(u32 ra, u32 rs, u32 rc) { @@ -3444,12 +3445,12 @@ private: void LWZ(u32 rd, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - CPU.GPR[rd] = vm::read32(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read32(VM_CAST(addr)); } void LWZU(u32 rd, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - CPU.GPR[rd] = vm::read32(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read32(VM_CAST(addr)); CPU.GPR[ra] = addr; } void LBZ(u32 rd, u32 ra, s32 d) @@ -3466,12 +3467,12 @@ private: void STW(u32 rs, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - vm::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); + vm::ps3::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); } void STWU(u32 rs, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - vm::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); + vm::ps3::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); CPU.GPR[ra] = addr; } void STB(u32 rs, u32 ra, s32 d) @@ -3488,34 +3489,34 @@ private: void LHZ(u32 rd, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - CPU.GPR[rd] = vm::read16(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read16(VM_CAST(addr)); } void LHZU(u32 rd, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - CPU.GPR[rd] = vm::read16(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read16(VM_CAST(addr)); CPU.GPR[ra] = addr; } void LHA(u32 rd, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - CPU.GPR[rd] = (s64)(s16)vm::read16(VM_CAST(addr)); + CPU.GPR[rd] = (s64)(s16)vm::ps3::read16(VM_CAST(addr)); } void LHAU(u32 rd, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - CPU.GPR[rd] = (s64)(s16)vm::read16(VM_CAST(addr)); + CPU.GPR[rd] = (s64)(s16)vm::ps3::read16(VM_CAST(addr)); CPU.GPR[ra] = addr; } void STH(u32 rs, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - vm::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); + vm::ps3::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); } void STHU(u32 rs, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - vm::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); + vm::ps3::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); CPU.GPR[ra] = addr; } void LMW(u32 rd, u32 ra, s32 d) @@ -3523,7 +3524,7 @@ private: u64 addr = ra ? CPU.GPR[ra] + d : d; for(u32 i=rd; i<32; ++i, addr += 4) { - CPU.GPR[i] = vm::read32(VM_CAST(addr)); + CPU.GPR[i] = vm::ps3::read32(VM_CAST(addr)); } } void STMW(u32 rs, u32 ra, s32 d) @@ -3531,7 +3532,7 @@ private: u64 addr = ra ? CPU.GPR[ra] + d : d; for(u32 i=rs; i<32; ++i, addr += 4) { - vm::write32(VM_CAST(addr), (u32)CPU.GPR[i]); + vm::ps3::write32(VM_CAST(addr), (u32)CPU.GPR[i]); } } void LFS(u32 frd, u32 ra, s32 d) @@ -3619,18 +3620,18 @@ private: void LD(u32 rd, u32 ra, s32 ds) { const u64 addr = ra ? CPU.GPR[ra] + ds : ds; - CPU.GPR[rd] = vm::read64(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read64(VM_CAST(addr)); } void LDU(u32 rd, u32 ra, s32 ds) { const u64 addr = CPU.GPR[ra] + ds; - CPU.GPR[rd] = vm::read64(VM_CAST(addr)); + CPU.GPR[rd] = vm::ps3::read64(VM_CAST(addr)); CPU.GPR[ra] = addr; } void LWA(u32 rd, u32 ra, s32 ds) { const u64 addr = ra ? CPU.GPR[ra] + ds : ds; - CPU.GPR[rd] = (s64)(s32)vm::read32(VM_CAST(addr)); + CPU.GPR[rd] = (s64)(s32)vm::ps3::read32(VM_CAST(addr)); } void FDIVS(u32 frd, u32 fra, u32 frb, u32 rc) {FDIV(frd, fra, frb, rc, true);} void FSUBS(u32 frd, u32 fra, u32 frb, u32 rc) {FSUB(frd, fra, frb, rc, true);} @@ -3684,12 +3685,12 @@ private: void STD(u32 rs, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - vm::write64(VM_CAST(addr), CPU.GPR[rs]); + vm::ps3::write64(VM_CAST(addr), CPU.GPR[rs]); } void STDU(u32 rs, u32 ra, s32 ds) { const u64 addr = CPU.GPR[ra] + ds; - vm::write64(VM_CAST(addr), CPU.GPR[rs]); + vm::ps3::write64(VM_CAST(addr), CPU.GPR[rs]); CPU.GPR[ra] = addr; } void MTFSB1(u32 crbd, u32 rc) diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index 306b1a3ba2..f0cf394d40 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #ifdef LLVM_AVAILABLE +#include "rpcs3/Ini.h" #include "Utilities/Log.h" #include "Emu/System.h" #include "Emu/Cell/PPUDisAsm.h" diff --git a/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp b/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp index d3af52b2e9..17c2c22313 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp @@ -29,6 +29,9 @@ #pragma warning(pop) #endif +extern void execute_ppu_func_by_index(PPUThread& ppu, u32 id); +extern void execute_syscall_by_index(PPUThread& ppu, u64 code); + using namespace llvm; using namespace ppu_recompiler_llvm; @@ -1787,7 +1790,7 @@ void Compiler::HACK(u32 index) { static u32 wrappedDoSyscall(PPUThread &CPU, u64 code) noexcept { try { - SysCalls::DoSyscall(CPU, code); + execute_syscall_by_index(CPU, code); return ExecutionStatus::ExecutionStatusBlockEnded; } catch (...) @@ -1812,7 +1815,7 @@ void Compiler::SC(u32 lev) { } break; case 3: - Call("PPUThread.FastStop", &PPUThread::fast_stop, m_state.args[CompileTaskState::Args::State]); + Call("PPUThread.fast_stop", &PPUThread::fast_stop, m_state.args[CompileTaskState::Args::State]); break; default: CompilationError(fmt::format("SC %u", lev)); @@ -2160,7 +2163,7 @@ void Compiler::TW(u32 to, u32 ra, u32 rb) { } void Compiler::LVSL(u32 vd, u32 ra, u32 rb) { - static const v128 s_lvsl_values[] = { + static const u64 s_lvsl_values[0x10][2] = { { 0x08090A0B0C0D0E0F, 0x0001020304050607 }, { 0x090A0B0C0D0E0F10, 0x0102030405060708 }, { 0x0A0B0C0D0E0F1011, 0x0203040506070809 }, @@ -2389,7 +2392,7 @@ void Compiler::CMPL(u32 crfd, u32 l, u32 ra, u32 rb) { } void Compiler::LVSR(u32 vd, u32 ra, u32 rb) { - static const v128 s_lvsr_values[] = { + static const u64 s_lvsr_values[0x10][2] = { { 0x18191A1B1C1D1E1F, 0x1011121314151617 }, { 0x1718191A1B1C1D1E, 0x0F10111213141516 }, { 0x161718191A1B1C1D, 0x0E0F101112131415 }, diff --git a/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp b/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp index c295698328..a55e332406 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp @@ -99,7 +99,7 @@ struct ppu_recompiler_llvm::PPUState { address = addr; for (int i = 0; i < (sizeof(mem_block) / 8); i++) { - mem_block[i] = vm::read64(address + (i * 8)); + mem_block[i] = vm::ps3::read64(address + (i * 8)); } } @@ -123,7 +123,7 @@ struct ppu_recompiler_llvm::PPUState { ppu.TB = TB; for (int i = 0; i < (sizeof(mem_block) / 8); i++) { - vm::write64(address + (i * 8), mem_block[i]); + vm::ps3::write64(address + (i * 8), mem_block[i]); } } diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index e9a5fa6660..884f58c9fd 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -5,8 +5,6 @@ #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/Modules.h" #include "Emu/Cell/PPUDecoder.h" #include "Emu/Cell/PPUInterpreter.h" #include "Emu/Cell/PPUInterpreter2.h" @@ -51,7 +49,7 @@ void ppu_decoder_cache_t::initialize(u32 addr, u32 size) inter->func = ppu_interpreter::NULL_OP; // decode PPU opcode - dec.Decode(vm::read32(pos)); + dec.Decode(vm::ps3::read32(pos)); // store function address pointer[pos / 4] = inter->func; @@ -81,13 +79,15 @@ PPUThread::~PPUThread() void PPUThread::dump_info() const { + extern std::string get_ps3_function_name(u64 fid); + if (~hle_code < 1024) { - LOG_SUCCESS(HLE, "Last syscall: %lld (%s)", ~hle_code, SysCalls::GetFuncName(hle_code)); + LOG_SUCCESS(HLE, "Last syscall: %lld (%s)", ~hle_code, get_ps3_function_name(hle_code)); } else if (hle_code) { - LOG_SUCCESS(HLE, "Last function: %s (0x%llx)", SysCalls::GetFuncName(hle_code), hle_code); + LOG_SUCCESS(HLE, "Last function: %s (0x%llx)", get_ps3_function_name(hle_code), hle_code); } CPUThread::dump_info(); @@ -214,7 +214,7 @@ int FPRdouble::Cmp(PPCdouble a, PPCdouble b) u64 PPUThread::get_stack_arg(s32 i) { - return vm::read64(VM_CAST(GPR[1] + 0x70 + 0x8 * (i - 9))); + return vm::ps3::read64(VM_CAST(GPR[1] + 0x70 + 0x8 * (i - 9))); } void PPUThread::fast_call(u32 addr, u32 rtoc) @@ -313,7 +313,7 @@ void PPUThread::task() if (!m_state.load()) { // call interpreter function - func(*this, { vm::read32(PC) }); + func(*this, { vm::ps3::read32(PC) }); // next instruction PC += 4; @@ -335,8 +335,8 @@ ppu_thread::ppu_thread(u32 entry, const std::string& name, u32 stack_size, s32 p if (entry) { - ppu->PC = vm::read32(entry); - ppu->GPR[2] = vm::read32(entry + 4); // rtoc + ppu->PC = vm::ps3::read32(entry); + ppu->GPR[2] = vm::ps3::read32(entry + 4); // rtoc } ppu->stack_size = stack_size ? stack_size : Emu.GetPrimaryStackSize(); diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 11a0e1047b..bfad145322 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -1012,3 +1012,20 @@ force_inline T cast_from_ppu_gpr(const u64 reg) { return cast_ppu_gpr::from_gpr(reg); } + +// flags set in ModuleFunc +enum : u32 +{ + MFF_FORCED_HLE = (1 << 0), // always call HLE function + MFF_NO_RETURN = (1 << 1), // uses EIF_USE_BRANCH flag with LLE, ignored with MFF_FORCED_HLE +}; + +// flags passed with index +enum : u32 +{ + EIF_SAVE_RTOC = (1 << 25), // save RTOC in [SP+0x28] before calling HLE/LLE function + EIF_PERFORM_BLR = (1 << 24), // do BLR after calling HLE/LLE function + EIF_USE_BRANCH = (1 << 23), // do only branch, LLE must be set, last_syscall must be zero + + EIF_FLAGS = 0x3800000, // all flags +}; diff --git a/rpcs3/Emu/SysCalls/FuncList.cpp b/rpcs3/Emu/SysCalls/FuncList.cpp index 359ee63438..95705cb01e 100644 --- a/rpcs3/Emu/SysCalls/FuncList.cpp +++ b/rpcs3/Emu/SysCalls/FuncList.cpp @@ -2,7 +2,7 @@ #include "Modules.h" #include "SysCalls.h" -std::string SysCalls::GetFuncName(const u64 fid) +std::string get_ps3_function_name(u64 fid) { // check syscalls switch (~fid) diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 2e09e1a813..3788a03dca 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -112,18 +112,18 @@ ModuleFunc* get_ppu_func_by_index(u32 index) return &g_ppu_func_list[index]; } -void execute_ppu_func_by_index(PPUThread& CPU, u32 index) +void execute_ppu_func_by_index(PPUThread& ppu, u32 index) { if (auto func = get_ppu_func_by_index(index)) { // save RTOC if necessary if (index & EIF_SAVE_RTOC) { - vm::write64(VM_CAST(CPU.GPR[1] + 0x28), CPU.GPR[2]); + vm::write64(VM_CAST(ppu.GPR[1] + 0x28), ppu.GPR[2]); } // save old syscall/NID value - const auto last_code = CPU.hle_code; + const auto last_code = ppu.hle_code; // branch directly to the LLE function if (index & EIF_USE_BRANCH) @@ -132,39 +132,39 @@ void execute_ppu_func_by_index(PPUThread& CPU, u32 index) if (last_code) { - throw EXCEPTION("This function cannot be called from the callback: %s (0x%llx)", SysCalls::GetFuncName(func->id), func->id); + throw EXCEPTION("This function cannot be called from the callback: %s (0x%llx)", get_ps3_function_name(func->id), func->id); } if (!func->lle_func) { - throw EXCEPTION("LLE function not set: %s (0x%llx)", SysCalls::GetFuncName(func->id), func->id); + throw EXCEPTION("LLE function not set: %s (0x%llx)", get_ps3_function_name(func->id), func->id); } if (func->flags & MFF_FORCED_HLE) { - throw EXCEPTION("Forced HLE enabled: %s (0x%llx)", SysCalls::GetFuncName(func->id), func->id); + throw EXCEPTION("Forced HLE enabled: %s (0x%llx)", get_ps3_function_name(func->id), func->id); } if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(HLE, "Branch to LLE function: %s (0x%llx)", SysCalls::GetFuncName(func->id), func->id); + LOG_NOTICE(HLE, "Branch to LLE function: %s (0x%llx)", get_ps3_function_name(func->id), func->id); } if (index & EIF_PERFORM_BLR) { - throw EXCEPTION("TODO: Branch with link: %s (0x%llx)", SysCalls::GetFuncName(func->id), func->id); + throw EXCEPTION("TODO: Branch with link: %s (0x%llx)", get_ps3_function_name(func->id), func->id); // CPU.LR = CPU.PC + 4; } const auto data = vm::get_ptr>(func->lle_func.addr()); - CPU.PC = data[0] - 4; - CPU.GPR[2] = data[1]; // set rtoc + ppu.PC = data[0] - 4; + ppu.GPR[2] = data[1]; // set rtoc return; } // change current syscall/NID value - CPU.hle_code = func->id; + ppu.hle_code = func->id; if (func->lle_func && !(func->flags & MFF_FORCED_HLE)) { @@ -176,49 +176,49 @@ void execute_ppu_func_by_index(PPUThread& CPU, u32 index) if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(HLE, "LLE function called: %s", SysCalls::GetFuncName(func->id)); + LOG_NOTICE(HLE, "LLE function called: %s", get_ps3_function_name(func->id)); } - CPU.fast_call(pc, rtoc); + ppu.fast_call(pc, rtoc); if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(HLE, "LLE function finished: %s -> 0x%llx", SysCalls::GetFuncName(func->id), CPU.GPR[3]); + LOG_NOTICE(HLE, "LLE function finished: %s -> 0x%llx", get_ps3_function_name(func->id), ppu.GPR[3]); } } else if (func->func) { if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(HLE, "HLE function called: %s", SysCalls::GetFuncName(func->id)); + LOG_NOTICE(HLE, "HLE function called: %s", get_ps3_function_name(func->id)); } - func->func(CPU); + func->func(ppu); if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(HLE, "HLE function finished: %s -> 0x%llx", SysCalls::GetFuncName(func->id), CPU.GPR[3]); + LOG_NOTICE(HLE, "HLE function finished: %s -> 0x%llx", get_ps3_function_name(func->id), ppu.GPR[3]); } } else { - LOG_ERROR(HLE, "Unimplemented function: %s -> CELL_OK", SysCalls::GetFuncName(func->id)); - CPU.GPR[3] = 0; + LOG_ERROR(HLE, "Unimplemented function: %s -> CELL_OK", get_ps3_function_name(func->id)); + ppu.GPR[3] = 0; } if (index & EIF_PERFORM_BLR) { // return if necessary - CPU.PC = VM_CAST(CPU.LR & ~3) - 4; + ppu.PC = VM_CAST(ppu.LR & ~3) - 4; } // execute module-specific error check - if ((s64)CPU.GPR[3] < 0 && func->module && func->module->on_error) + if ((s64)ppu.GPR[3] < 0 && func->module && func->module->on_error) { - func->module->on_error(CPU.GPR[3], func); + func->module->on_error(ppu.GPR[3], func); } - CPU.hle_code = last_code; + ppu.hle_code = last_code; } else { diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index 8c71731e64..c1f2d64ade 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -9,23 +9,6 @@ namespace vm { using namespace ps3; } template class Module; -// flags set in ModuleFunc -enum : u32 -{ - MFF_FORCED_HLE = (1 << 0), // always call HLE function - MFF_NO_RETURN = (1 << 1), // uses EIF_USE_BRANCH flag with LLE, ignored with MFF_FORCED_HLE -}; - -// flags passed with index -enum : u32 -{ - EIF_SAVE_RTOC = (1 << 25), // save RTOC in [SP+0x28] before calling HLE/LLE function - EIF_PERFORM_BLR = (1 << 24), // do BLR after calling HLE/LLE function - EIF_USE_BRANCH = (1 << 23), // do only branch, LLE must be set, last_syscall must be zero - - EIF_FLAGS = 0x3800000, // all flags -}; - struct ModuleFunc { u32 id; @@ -153,7 +136,8 @@ void add_variable(u32 nid, Module<>* module, const char* name, u32(*addr)()); ModuleFunc* get_ppu_func_by_nid(u32 nid, u32* out_index = nullptr); ModuleFunc* get_ppu_func_by_index(u32 index); ModuleVariable* get_variable_by_nid(u32 nid); -void execute_ppu_func_by_index(PPUThread& CPU, u32 id); +void execute_ppu_func_by_index(PPUThread& ppu, u32 id); +extern std::string get_ps3_function_name(u64 fid); void clear_ppu_functions(); u32 get_function_id(const char* name); diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 4d765a46dd..24b1b4e1db 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -37,7 +37,7 @@ void null_func(PPUThread& ppu) { const u64 code = ppu.GPR[11]; - LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", code, SysCalls::GetFuncName(~code)); + LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", code, get_ps3_function_name(~code)); ppu.GPR[3] = 0; } @@ -891,27 +891,27 @@ const ppu_func_caller g_sc_table[1024] = null_func, null_func, null_func, BIND_FUNC(cellGcmCallback), //1023 UNS }; -void SysCalls::DoSyscall(PPUThread& CPU, u64 code) +void execute_syscall_by_index(PPUThread& ppu, u64 code) { if (code >= 1024) { throw EXCEPTION("Invalid syscall number (0x%llx)", code); } - auto last_code = CPU.hle_code; - CPU.hle_code = ~code; + auto last_code = ppu.hle_code; + ppu.hle_code = ~code; if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(PPU, "Syscall %lld called: %s", code, SysCalls::GetFuncName(~code)); + LOG_NOTICE(PPU, "Syscall %lld called: %s", code, get_ps3_function_name(~code)); } - g_sc_table[code](CPU); + g_sc_table[code](ppu); if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(PPU, "Syscall %lld finished: %s -> 0x%llx", code, SysCalls::GetFuncName(~code), CPU.GPR[3]); + LOG_NOTICE(PPU, "Syscall %lld finished: %s -> 0x%llx", code, get_ps3_function_name(~code), ppu.GPR[3]); } - CPU.hle_code = last_code; + ppu.hle_code = last_code; } diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 888f7aa617..a12fd14aec 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -19,11 +19,5 @@ public: } }; -class PPUThread; - -class SysCalls -{ -public: - static void DoSyscall(PPUThread& CPU, u64 code); - static std::string GetFuncName(const u64 fid); -}; +void execute_syscall_by_index(class PPUThread& ppu, u64 code); +std::string get_ps3_function_name(u64 fid); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp index 72b8157e8b..06d9843680 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp @@ -83,7 +83,7 @@ s32 prx_load_module(std::string path, u64 flags, vm::ptrlle_func && !(func->flags & MFF_FORCED_HLE); - sys_prx.Error("Imported %sfunction '%s' in '%s' module (0x%x)", (is_lle ? "LLE " : ""), SysCalls::GetFuncName(nid), module_.first, addr); + sys_prx.Error("Imported %sfunction '%s' in '%s' module (0x%x)", (is_lle ? "LLE " : ""), get_ps3_function_name(nid), module_.first, addr); } if (!patch_ppu_import(addr, index)) diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index 5d4661e961..4166d27c13 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -167,8 +167,8 @@ namespace loader module.exports[fnid] = fstub; - //LOG_NOTICE(LOADER, "Exported function '%s' in '%s' module (LLE)", SysCalls::GetFuncName(fnid).c_str(), module_name.c_str()); - LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetFuncName(fnid).c_str(), (u32)fstub); + //LOG_NOTICE(LOADER, "Exported function '%s' in '%s' module (LLE)", get_ps3_function_name(fnid), module_name); + LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename, get_ps3_function_name(fnid), (u32)fstub); } } @@ -204,7 +204,7 @@ namespace loader module.imports[fnid] = fstub; - LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetFuncName(fnid).c_str(), (u32)fstub); + LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename, get_ps3_function_name(fnid), (u32)fstub); } } } @@ -449,7 +449,7 @@ namespace loader if (!vm::check_addr(addr, 8) || !vm::check_addr(i_addr = vm::read32(addr), 4)) { - LOG_ERROR(LOADER, "Failed to inject code for exported function '%s' (opd=0x%x, 0x%x)", SysCalls::GetFuncName(nid), addr, i_addr); + LOG_ERROR(LOADER, "Failed to inject code for exported function '%s' (opd=0x%x, 0x%x)", get_ps3_function_name(nid), addr, i_addr); } else { @@ -470,18 +470,18 @@ namespace loader if (!func) { - LOG_ERROR(LOADER, "Unknown function '%s' (0x%x)", SysCalls::GetFuncName(nid), addr); + LOG_ERROR(LOADER, "Unknown function '%s' (0x%x)", get_ps3_function_name(nid), addr); index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr)); } else { - LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", SysCalls::GetFuncName(nid), addr); + LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", get_ps3_function_name(nid), addr); } if (!patch_ppu_import(addr, index)) { - LOG_ERROR(LOADER, "Failed to inject code for function '%s' (0x%x)", SysCalls::GetFuncName(nid), addr); + LOG_ERROR(LOADER, "Failed to inject code for function '%s' (0x%x)", get_ps3_function_name(nid), addr); } } } @@ -708,7 +708,7 @@ namespace loader if (!func) { - LOG_ERROR(LOADER, "Unknown function '%s' in '%s' module (0x%x)", SysCalls::GetFuncName(nid), module_name, addr); + LOG_ERROR(LOADER, "Unknown function '%s' in '%s' module (0x%x)", get_ps3_function_name(nid), module_name, addr); index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr)); } @@ -716,7 +716,7 @@ namespace loader { const bool is_lle = func->lle_func && !(func->flags & MFF_FORCED_HLE); - LOG_NOTICE(LOADER, "Imported %sfunction '%s' in '%s' module (0x%x)", is_lle ? "LLE " : "", SysCalls::GetFuncName(nid), module_name, addr); + LOG_NOTICE(LOADER, "Imported %sfunction '%s' in '%s' module (0x%x)", is_lle ? "LLE " : "", get_ps3_function_name(nid), module_name, addr); } if (!patch_ppu_import(addr, index))