mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 13:31:27 +12:00
be_t (se_t) optimizations
This commit is contained in:
parent
59f1077a36
commit
9d68c16c62
14 changed files with 240 additions and 90 deletions
|
@ -374,6 +374,9 @@ inline v128 operator ~(const v128& other)
|
||||||
return v128::from64(~other._u64[0], ~other._u64[1]);
|
return v128::from64(~other._u64[0], ~other._u64[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define IS_INTEGER(t) (std::is_integral<t>::value || std::is_enum<t>::value)
|
||||||
|
#define IS_BINARY_COMPARABLE(t1, t2) (IS_INTEGER(t1) && IS_INTEGER(t2) && sizeof(t1) == sizeof(t2))
|
||||||
|
|
||||||
template<typename T, std::size_t Size = sizeof(T)> struct se_storage
|
template<typename T, std::size_t Size = sizeof(T)> struct se_storage
|
||||||
{
|
{
|
||||||
static_assert(!Size, "Bad se_storage<> type");
|
static_assert(!Size, "Bad se_storage<> type");
|
||||||
|
@ -383,6 +386,11 @@ template<typename T> struct se_storage<T, 2>
|
||||||
{
|
{
|
||||||
using type = u16;
|
using type = u16;
|
||||||
|
|
||||||
|
static constexpr u16 swap(u16 src)
|
||||||
|
{
|
||||||
|
return (src >> 8) | (src << 8);
|
||||||
|
}
|
||||||
|
|
||||||
static inline u16 to(const T& src)
|
static inline u16 to(const T& src)
|
||||||
{
|
{
|
||||||
return _byteswap_ushort(reinterpret_cast<const u16&>(src));
|
return _byteswap_ushort(reinterpret_cast<const u16&>(src));
|
||||||
|
@ -399,6 +407,11 @@ template<typename T> struct se_storage<T, 4>
|
||||||
{
|
{
|
||||||
using type = u32;
|
using type = u32;
|
||||||
|
|
||||||
|
static constexpr u32 swap(u32 src)
|
||||||
|
{
|
||||||
|
return (src >> 24) | (src << 24) | ((src >> 8) & 0x0000ff00) | ((src << 8) & 0x00ff0000);
|
||||||
|
}
|
||||||
|
|
||||||
static inline u32 to(const T& src)
|
static inline u32 to(const T& src)
|
||||||
{
|
{
|
||||||
return _byteswap_ulong(reinterpret_cast<const u32&>(src));
|
return _byteswap_ulong(reinterpret_cast<const u32&>(src));
|
||||||
|
@ -415,6 +428,17 @@ template<typename T> struct se_storage<T, 8>
|
||||||
{
|
{
|
||||||
using type = u64;
|
using type = u64;
|
||||||
|
|
||||||
|
static constexpr u64 swap(u64 src)
|
||||||
|
{
|
||||||
|
return (src >> 56) | (src << 56) |
|
||||||
|
((src >> 40) & 0x000000000000ff00) |
|
||||||
|
((src >> 24) & 0x0000000000ff0000) |
|
||||||
|
((src >> 8) & 0x00000000ff000000) |
|
||||||
|
((src << 8) & 0x000000ff00000000) |
|
||||||
|
((src << 24) & 0x0000ff0000000000) |
|
||||||
|
((src << 40) & 0x00ff000000000000);
|
||||||
|
}
|
||||||
|
|
||||||
static inline u64 to(const T& src)
|
static inline u64 to(const T& src)
|
||||||
{
|
{
|
||||||
return _byteswap_uint64(reinterpret_cast<const u64&>(src));
|
return _byteswap_uint64(reinterpret_cast<const u64&>(src));
|
||||||
|
@ -465,16 +489,17 @@ template<typename T1, typename T2> struct se_convert
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct se_raw_tag_t {} const se_raw{};
|
||||||
|
|
||||||
template<typename T, bool Se = true> class se_t
|
template<typename T, bool Se = true> class se_t
|
||||||
{
|
{
|
||||||
using type = std::remove_cv_t<T>;
|
using type = std::remove_cv_t<T>;
|
||||||
using stype = se_storage_t<std::remove_cv_t<T>>;
|
using stype = se_storage_t<type>;
|
||||||
using storage = se_storage<std::remove_cv_t<T>>;
|
using storage = se_storage<type>;
|
||||||
|
|
||||||
stype m_data;
|
stype m_data;
|
||||||
|
|
||||||
static_assert(!std::is_class<type>::value || std::is_same<type, u128>::value, "se_t<> error: invalid type (class or structure)");
|
static_assert(!std::is_union<type>::value && !std::is_class<type>::value || std::is_same<type, v128>::value || std::is_same<type, u128>::value, "se_t<> error: invalid type (struct or union)");
|
||||||
static_assert(!std::is_union<type>::value || std::is_same<type, v128>::value || std::is_same<type, u128>::value, "se_t<> error: invalid type (union)");
|
|
||||||
static_assert(!std::is_pointer<type>::value, "se_t<> error: invalid type (pointer)");
|
static_assert(!std::is_pointer<type>::value, "se_t<> error: invalid type (pointer)");
|
||||||
static_assert(!std::is_reference<type>::value, "se_t<> error: invalid type (reference)");
|
static_assert(!std::is_reference<type>::value, "se_t<> error: invalid type (reference)");
|
||||||
static_assert(!std::is_array<type>::value, "se_t<> error: invalid type (array)");
|
static_assert(!std::is_array<type>::value, "se_t<> error: invalid type (array)");
|
||||||
|
@ -484,59 +509,106 @@ template<typename T, bool Se = true> class se_t
|
||||||
public:
|
public:
|
||||||
se_t() = default;
|
se_t() = default;
|
||||||
|
|
||||||
se_t(const se_t&) = default;
|
se_t(const se_t& right) = default;
|
||||||
|
|
||||||
inline se_t(const type& value)
|
template<typename CT, typename = std::enable_if_t<std::is_constructible<type, CT>::value && !std::is_same<se_t<type>, std::decay_t<CT>>::value>> inline se_t(const CT& value)
|
||||||
: m_data(storage::to(value))
|
: m_data(storage::to(value))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// construct directly from raw data (don't use)
|
||||||
|
inline se_t(const stype& raw_value, const se_raw_tag_t&)
|
||||||
|
: m_data(raw_value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
inline type value() const
|
inline type value() const
|
||||||
{
|
{
|
||||||
return storage::from(m_data);
|
return storage::from(m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const stype& data() const
|
// access underlying raw data (don't use)
|
||||||
|
inline const stype& raw_data() const
|
||||||
{
|
{
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
se_t& operator =(const se_t&) = default;
|
se_t& operator =(const se_t&) = default;
|
||||||
|
|
||||||
template<typename CT> std::enable_if_t<std::is_assignable<type&, CT>::value, se_t&> operator =(const CT& value)
|
template<typename CT> inline std::enable_if_t<std::is_assignable<type&, CT>::value && !std::is_same<se_t<type>, std::decay_t<CT>>::value, se_t&> operator =(const CT& value)
|
||||||
{
|
{
|
||||||
return m_data = storage::to(value), *this;
|
return m_data = storage::to(value), *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator type() const
|
inline operator type() const
|
||||||
{
|
{
|
||||||
return value();
|
return value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
explicit inline operator bool() const
|
||||||
|
{
|
||||||
|
static_assert(std::is_convertible<T, bool>::value, "Illegal conversion to bool");
|
||||||
|
|
||||||
|
return m_data != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T, T2), se_t&> operator &=(const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return m_data &= right.raw_data(), *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename CT> inline std::enable_if_t<std::is_integral<T>::value && std::is_convertible<CT, T>::value, se_t&> operator &=(const CT& right)
|
||||||
|
{
|
||||||
|
return m_data &= storage::to(right), *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T, T2), se_t&> operator |=(const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return m_data |= right.raw_data(), *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename CT> inline std::enable_if_t<std::is_integral<T>::value && std::is_convertible<CT, T>::value, se_t&> operator |=(const CT& right)
|
||||||
|
{
|
||||||
|
return m_data |= storage::to(right), *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T, T2), se_t&> operator ^=(const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return m_data ^= right.raw_data(), *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename CT> inline std::enable_if_t<std::is_integral<T>::value && std::is_convertible<CT, T>::value, se_t&> operator ^=(const CT& right)
|
||||||
|
{
|
||||||
|
return m_data ^= storage::to(right), *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> class se_t<T, false>
|
template<typename T> class se_t<T, false>
|
||||||
{
|
{
|
||||||
using type = std::remove_cv_t<T>;
|
using type = std::remove_cv_t<T>;
|
||||||
using stype = se_storage_t<std::remove_cv_t<T>>;
|
|
||||||
using storage = se_storage<std::remove_cv_t<T>>;
|
|
||||||
|
|
||||||
type m_data;
|
type m_data;
|
||||||
|
|
||||||
static_assert(!std::is_class<type>::value || std::is_same<type, u128>::value, "se_t<> error: invalid type (class or structure)");
|
static_assert(!std::is_union<type>::value && !std::is_class<type>::value || std::is_same<type, v128>::value || std::is_same<type, u128>::value, "se_t<> error: invalid type (struct or union)");
|
||||||
static_assert(!std::is_union<type>::value || std::is_same<type, v128>::value || std::is_same<T, u128>::value, "se_t<> error: invalid type (union)");
|
|
||||||
static_assert(!std::is_pointer<type>::value, "se_t<> error: invalid type (pointer)");
|
static_assert(!std::is_pointer<type>::value, "se_t<> error: invalid type (pointer)");
|
||||||
static_assert(!std::is_reference<type>::value, "se_t<> error: invalid type (reference)");
|
static_assert(!std::is_reference<type>::value, "se_t<> error: invalid type (reference)");
|
||||||
static_assert(!std::is_array<type>::value, "se_t<> error: invalid type (array)");
|
static_assert(!std::is_array<type>::value, "se_t<> error: invalid type (array)");
|
||||||
static_assert(!std::is_enum<type>::value, "se_t<> error: invalid type (enumeration), use integral type instead");
|
static_assert(!std::is_enum<type>::value, "se_t<> error: invalid type (enumeration), use integral type instead");
|
||||||
static_assert(alignof(type) == alignof(stype), "se_t<> error: unexpected alignment");
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
se_t() = default;
|
se_t() = default;
|
||||||
|
|
||||||
se_t(const se_t&) = default;
|
se_t(const se_t&) = default;
|
||||||
|
|
||||||
inline se_t(const type& value)
|
template<typename CT, typename = std::enable_if_t<std::is_constructible<type, CT>::value && !std::is_same<se_t<type>, std::decay_t<CT>>::value>> inline se_t(CT&& value)
|
||||||
: m_data(value)
|
: m_data(std::forward<CT>(value))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,34 +617,34 @@ public:
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const stype& data() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<const stype&>(m_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
se_t& operator =(const se_t& value) = default;
|
se_t& operator =(const se_t& value) = default;
|
||||||
|
|
||||||
template<typename CT> std::enable_if_t<std::is_assignable<type&, CT>::value, se_t&> operator =(const CT& value)
|
template<typename CT> inline std::enable_if_t<std::is_assignable<type&, CT>::value && !std::is_same<se_t<type>, std::decay_t<CT>>::value, se_t&> operator =(const CT& value)
|
||||||
{
|
{
|
||||||
return m_data = value, *this;
|
return m_data = value, *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator type() const
|
inline operator type() const
|
||||||
{
|
{
|
||||||
return value();
|
return value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename CT> inline std::enable_if_t<std::is_integral<T>::value && std::is_convertible<CT, T>::value, se_t&> operator &=(const CT& right)
|
||||||
|
{
|
||||||
|
return m_data &= right, *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CT> inline std::enable_if_t<std::is_integral<T>::value && std::is_convertible<CT, T>::value, se_t&> operator |=(const CT& right)
|
||||||
|
{
|
||||||
|
return m_data |= right, *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CT> inline std::enable_if_t<std::is_integral<T>::value && std::is_convertible<CT, T>::value, se_t&> operator ^=(const CT& right)
|
||||||
|
{
|
||||||
|
return m_data ^= right, *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2> inline std::enable_if_t<std::is_same<T1, T2>::value && std::is_integral<T1>::value, bool> operator ==(const se_t<T1>& left, const se_t<T2>& right)
|
|
||||||
{
|
|
||||||
return left.data() == right.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T1, typename T2> inline std::enable_if_t<std::is_same<T1, T2>::value && std::is_integral<T1>::value, bool> operator !=(const se_t<T1>& left, const se_t<T2>& right)
|
|
||||||
{
|
|
||||||
return left.data() != right.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, bool Se, typename T1> inline se_t<T, Se>& operator +=(se_t<T, Se>& left, const T1& right)
|
template<typename T, bool Se, typename T1> inline se_t<T, Se>& operator +=(se_t<T, Se>& left, const T1& right)
|
||||||
{
|
{
|
||||||
auto value = left.value();
|
auto value = left.value();
|
||||||
|
@ -615,24 +687,6 @@ template<typename T, bool Se, typename T1> inline se_t<T, Se>& operator >>=(se_t
|
||||||
return left = (value >>= right);
|
return left = (value >>= right);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool Se, typename T1> inline se_t<T, Se>& operator &=(se_t<T, Se>& left, const T1& right)
|
|
||||||
{
|
|
||||||
auto value = left.value();
|
|
||||||
return left = (value &= right);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, bool Se, typename T1> inline se_t<T, Se>& operator |=(se_t<T, Se>& left, const T1& right)
|
|
||||||
{
|
|
||||||
auto value = left.value();
|
|
||||||
return left = (value |= right);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, bool Se, typename T1> inline se_t<T, Se>& operator ^=(se_t<T, Se>& left, const T1& right)
|
|
||||||
{
|
|
||||||
auto value = left.value();
|
|
||||||
return left = (value ^= right);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, bool Se> inline se_t<T, Se> operator ++(se_t<T, Se>& left, int)
|
template<typename T, bool Se> inline se_t<T, Se> operator ++(se_t<T, Se>& left, int)
|
||||||
{
|
{
|
||||||
auto value = left.value();
|
auto value = left.value();
|
||||||
|
@ -661,6 +715,102 @@ template<typename T, bool Se> inline se_t<T, Se>& operator --(se_t<T, Se>& right
|
||||||
return right = --value;
|
return right = --value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2), bool> operator ==(const se_t<T1>& left, const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return left.raw_data() == right.raw_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2), bool> operator ==(const se_t<T1>& left, const T2& right)
|
||||||
|
{
|
||||||
|
return left.raw_data() == se_storage<T2>::to(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2), bool> operator ==(const T1& left, const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return se_storage<T1>::to(left) == right.raw_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2), bool> operator !=(const se_t<T1>& left, const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return left.raw_data() != right.raw_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2), bool> operator !=(const se_t<T1>& left, const T2& right)
|
||||||
|
{
|
||||||
|
return left.raw_data() != se_storage<T2>::to(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2), bool> operator !=(const T1& left, const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return se_storage<T1>::to(left) != right.raw_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2) && sizeof(T1) >= 4, se_t<decltype(T1() & T2())>> operator &(const se_t<T1>& left, const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return{ static_cast<se_storage_t<T1>>(left.raw_data() & right.raw_data()), se_raw };
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2) && sizeof(T1) >= 4, se_t<decltype(T1() & T2())>> operator &(const se_t<T1>& left, const T2& right)
|
||||||
|
{
|
||||||
|
return{ static_cast<se_storage_t<T1>>(left.raw_data() & se_storage<T2>::to(right)), se_raw };
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2) && sizeof(T1) >= 4, se_t<decltype(T1() & T2())>> operator &(const T1& left, const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return{ static_cast<se_storage_t<T1>>(se_storage<T1>::to(left) & right.raw_data()), se_raw };
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2) && sizeof(T1) >= 4, se_t<decltype(T1() | T2())>> operator |(const se_t<T1>& left, const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return{ static_cast<se_storage_t<T1>>(left.raw_data() | right.raw_data()), se_raw };
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2) && sizeof(T1) >= 4, se_t<decltype(T1() | T2())>> operator |(const se_t<T1>& left, const T2& right)
|
||||||
|
{
|
||||||
|
return{ static_cast<se_storage_t<T1>>(left.raw_data() | se_storage<T2>::to(right)), se_raw };
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2) && sizeof(T1) >= 4, se_t<decltype(T1() | T2())>> operator |(const T1& left, const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return{ static_cast<se_storage_t<T1>>(se_storage<T1>::to(left) | right.raw_data()), se_raw };
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2) && sizeof(T1) >= 4, se_t<decltype(T1() ^ T2())>> operator ^(const se_t<T1>& left, const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return{ static_cast<se_storage_t<T1>>(left.raw_data() ^ right.raw_data()), se_raw };
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2) && sizeof(T1) >= 4, se_t<decltype(T1() ^ T2())>> operator ^(const se_t<T1>& left, const T2& right)
|
||||||
|
{
|
||||||
|
return{ static_cast<se_storage_t<T1>>(left.raw_data() ^ se_storage<T2>::to(right)), se_raw };
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T1, typename T2> inline std::enable_if_t<IS_BINARY_COMPARABLE(T1, T2) && sizeof(T1) >= 4, se_t<decltype(T1() ^ T2())>> operator ^(const T1& left, const se_t<T2>& right)
|
||||||
|
{
|
||||||
|
return{ static_cast<se_storage_t<T1>>(se_storage<T1>::to(left) ^ right.raw_data()), se_raw };
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimization
|
||||||
|
template<typename T> inline std::enable_if_t<IS_INTEGER(T) && sizeof(T) >= 4, se_t<decltype(~T())>> operator ~(const se_t<T>& right)
|
||||||
|
{
|
||||||
|
return{ static_cast<se_storage_t<T>>(~right.raw_data()), se_raw };
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef IS_LE_MACHINE
|
#ifdef IS_LE_MACHINE
|
||||||
template<typename T> using be_t = se_t<T, true>;
|
template<typename T> using be_t = se_t<T, true>;
|
||||||
template<typename T> using le_t = se_t<T, false>;
|
template<typename T> using le_t = se_t<T, false>;
|
||||||
|
|
|
@ -272,10 +272,10 @@ void hook_ppu_func(vm::ptr<u32> base, u32 pos, u32 size)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 data = sub.ops[x].data.data();
|
const be_t<u32> data = sub.ops[x].data;
|
||||||
const u32 mask = sub.ops[x].mask.data();
|
const be_t<u32> mask = sub.ops[x].mask;
|
||||||
|
|
||||||
const bool match = (base[k].data() & mask) == data;
|
const bool match = (base[k] & mask) == data;
|
||||||
|
|
||||||
switch (sub.ops[x].type)
|
switch (sub.ops[x].type)
|
||||||
{
|
{
|
||||||
|
@ -301,8 +301,8 @@ void hook_ppu_func(vm::ptr<u32> base, u32 pos, u32 size)
|
||||||
}
|
}
|
||||||
case SPET_LABEL:
|
case SPET_LABEL:
|
||||||
{
|
{
|
||||||
const auto addr = (base + k--).addr();
|
const u32 addr = (base + k--).addr();
|
||||||
const auto lnum = data;
|
const u32 lnum = data;
|
||||||
const auto label = sub.labels.find(lnum);
|
const auto label = sub.labels.find(lnum);
|
||||||
|
|
||||||
if (label == sub.labels.end()) // register the label
|
if (label == sub.labels.end()) // register the label
|
||||||
|
|
|
@ -631,7 +631,7 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<u32> addr, vm::ptr<u64> size)
|
||||||
const u32 position = VM_CAST(file->st_buffer + copied % file->st_ringbuf_size);
|
const u32 position = VM_CAST(file->st_buffer + copied % file->st_ringbuf_size);
|
||||||
const u64 total_read = file->st_total_read.load();
|
const u64 total_read = file->st_total_read.load();
|
||||||
|
|
||||||
if ((*size = std::min<u64>(file->st_ringbuf_size - (position - file->st_buffer), total_read - copied)).data())
|
if ((*size = std::min<u64>(file->st_ringbuf_size - (position - file->st_buffer), total_read - copied)))
|
||||||
{
|
{
|
||||||
*addr = position;
|
*addr = position;
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,7 +321,7 @@ s32 spursAttachLv2EventQueue(PPUThread& ppu, vm::ptr<CellSpurs> spurs, u32 queue
|
||||||
return CELL_SPURS_CORE_ERROR_ALIGN;
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spurs->exception.data())
|
if (spurs->exception)
|
||||||
{
|
{
|
||||||
return CELL_SPURS_CORE_ERROR_STAT;
|
return CELL_SPURS_CORE_ERROR_STAT;
|
||||||
}
|
}
|
||||||
|
@ -380,7 +380,7 @@ s32 spursDetachLv2EventQueue(vm::ptr<CellSpurs> spurs, u8 spuPort, bool spursCre
|
||||||
return CELL_SPURS_CORE_ERROR_ALIGN;
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!spursCreated && spurs->exception.data())
|
if (!spursCreated && spurs->exception)
|
||||||
{
|
{
|
||||||
return CELL_SPURS_CORE_ERROR_STAT;
|
return CELL_SPURS_CORE_ERROR_STAT;
|
||||||
}
|
}
|
||||||
|
@ -555,7 +555,7 @@ s32 spursCreateHandler(vm::ptr<CellSpurs> spurs, u32 ppuPriority)
|
||||||
/// Invoke event handlers
|
/// Invoke event handlers
|
||||||
s32 spursInvokeEventHandlers(PPUThread& ppu, vm::ptr<CellSpurs::EventPortMux> eventPortMux)
|
s32 spursInvokeEventHandlers(PPUThread& ppu, vm::ptr<CellSpurs::EventPortMux> eventPortMux)
|
||||||
{
|
{
|
||||||
if (eventPortMux->reqPending.exchange(0).data())
|
if (eventPortMux->reqPending.exchange(0))
|
||||||
{
|
{
|
||||||
const vm::ptr<CellSpurs::EventHandlerListNode> handlerList = eventPortMux->handlerList.exchange(vm::null);
|
const vm::ptr<CellSpurs::EventHandlerListNode> handlerList = eventPortMux->handlerList.exchange(vm::null);
|
||||||
|
|
||||||
|
@ -1656,7 +1656,7 @@ s32 cellSpursSetMaxContention(vm::ptr<CellSpurs> spurs, u32 wid, u32 maxContenti
|
||||||
return CELL_SPURS_CORE_ERROR_SRCH;
|
return CELL_SPURS_CORE_ERROR_SRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spurs->exception.data())
|
if (spurs->exception)
|
||||||
{
|
{
|
||||||
return CELL_SPURS_CORE_ERROR_STAT;
|
return CELL_SPURS_CORE_ERROR_STAT;
|
||||||
}
|
}
|
||||||
|
@ -1700,7 +1700,7 @@ s32 cellSpursSetPriorities(vm::ptr<CellSpurs> spurs, u32 wid, vm::cptr<u8> prior
|
||||||
return CELL_SPURS_CORE_ERROR_SRCH;
|
return CELL_SPURS_CORE_ERROR_SRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spurs->exception.data())
|
if (spurs->exception)
|
||||||
{
|
{
|
||||||
return CELL_SPURS_CORE_ERROR_STAT;
|
return CELL_SPURS_CORE_ERROR_STAT;
|
||||||
}
|
}
|
||||||
|
@ -1810,7 +1810,7 @@ s32 cellSpursSetGlobalExceptionEventHandler(vm::ptr<CellSpurs> spurs, vm::ptr<Ce
|
||||||
return CELL_SPURS_CORE_ERROR_ALIGN;
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spurs->exception.data())
|
if (spurs->exception)
|
||||||
{
|
{
|
||||||
return CELL_SPURS_CORE_ERROR_STAT;
|
return CELL_SPURS_CORE_ERROR_STAT;
|
||||||
}
|
}
|
||||||
|
@ -2182,7 +2182,7 @@ s32 spursAddWorkload(
|
||||||
return CELL_SPURS_POLICY_MODULE_ERROR_INVAL;
|
return CELL_SPURS_POLICY_MODULE_ERROR_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spurs->exception.data())
|
if (spurs->exception)
|
||||||
{
|
{
|
||||||
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
||||||
}
|
}
|
||||||
|
@ -2398,7 +2398,7 @@ s32 cellSpursWakeUp(PPUThread& ppu, vm::ptr<CellSpurs> spurs)
|
||||||
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spurs->exception.data())
|
if (spurs->exception)
|
||||||
{
|
{
|
||||||
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
||||||
}
|
}
|
||||||
|
@ -2433,7 +2433,7 @@ s32 cellSpursSendWorkloadSignal(vm::ptr<CellSpurs> spurs, u32 wid)
|
||||||
return CELL_SPURS_POLICY_MODULE_ERROR_INVAL;
|
return CELL_SPURS_POLICY_MODULE_ERROR_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((spurs->wklEnabled.load() & (0x80000000u >> wid)) == 0)
|
if (!(spurs->wklEnabled.load() & (0x80000000u >> wid)))
|
||||||
{
|
{
|
||||||
return CELL_SPURS_POLICY_MODULE_ERROR_SRCH;
|
return CELL_SPURS_POLICY_MODULE_ERROR_SRCH;
|
||||||
}
|
}
|
||||||
|
@ -2504,7 +2504,7 @@ s32 cellSpursReadyCountStore(vm::ptr<CellSpurs> spurs, u32 wid, u32 value)
|
||||||
return CELL_SPURS_POLICY_MODULE_ERROR_SRCH;
|
return CELL_SPURS_POLICY_MODULE_ERROR_SRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spurs->exception.data() || spurs->wklState(wid).load() != 2)
|
if (spurs->exception || spurs->wklState(wid).load() != 2)
|
||||||
{
|
{
|
||||||
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
||||||
}
|
}
|
||||||
|
@ -2630,7 +2630,7 @@ s32 _cellSpursWorkloadFlagReceiver(vm::ptr<CellSpurs> spurs, u32 wid, u32 is_set
|
||||||
return CELL_SPURS_POLICY_MODULE_ERROR_SRCH;
|
return CELL_SPURS_POLICY_MODULE_ERROR_SRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spurs->exception.data())
|
if (spurs->exception)
|
||||||
{
|
{
|
||||||
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -331,7 +331,7 @@ s32 cellSyncRwmWrite(PPUThread& ppu, vm::ptr<CellSyncRwm> rwm, vm::cptr<void> bu
|
||||||
vm::wait_op(ppu, rwm.addr(), 4, WRAP_EXPR(rwm->ctrl.atomic_op(&sync_rwm_t::try_write_begin)));
|
vm::wait_op(ppu, rwm.addr(), 4, WRAP_EXPR(rwm->ctrl.atomic_op(&sync_rwm_t::try_write_begin)));
|
||||||
|
|
||||||
// wait until `readers` is zero
|
// wait until `readers` is zero
|
||||||
vm::wait_op(ppu, rwm.addr(), 4, WRAP_EXPR(!rwm->ctrl.load().readers.data()));
|
vm::wait_op(ppu, rwm.addr(), 4, WRAP_EXPR(!rwm->ctrl.load().readers));
|
||||||
|
|
||||||
// copy data from buffer
|
// copy data from buffer
|
||||||
std::memcpy(rwm->buffer.get_ptr(), buffer.get_ptr(), rwm->size);
|
std::memcpy(rwm->buffer.get_ptr(), buffer.get_ptr(), rwm->size);
|
||||||
|
@ -746,7 +746,7 @@ s32 cellSyncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::cptr<void> buf
|
||||||
const auto old = queue->init.load();
|
const auto old = queue->init.load();
|
||||||
auto init = old;
|
auto init = old;
|
||||||
|
|
||||||
if (old.data())
|
if (old)
|
||||||
{
|
{
|
||||||
if (sdk_ver > 0x17ffff && old != 2)
|
if (sdk_ver > 0x17ffff && old != 2)
|
||||||
{
|
{
|
||||||
|
@ -837,7 +837,7 @@ s32 _cellSyncLFQueueGetPushPointer(PPUThread& ppu, vm::ptr<CellSyncLFQueue> queu
|
||||||
|
|
||||||
s32 var2 = (s16)push.m_h8;
|
s32 var2 = (s16)push.m_h8;
|
||||||
s32 res;
|
s32 res;
|
||||||
if (useEventQueue && ((s32)push.m_h5 != var2 || push.m_h7.data() != 0))
|
if (useEventQueue && ((s32)push.m_h5 != var2 || push.m_h7))
|
||||||
{
|
{
|
||||||
res = CELL_SYNC_ERROR_BUSY;
|
res = CELL_SYNC_ERROR_BUSY;
|
||||||
}
|
}
|
||||||
|
@ -884,7 +884,7 @@ s32 _cellSyncLFQueueGetPushPointer(PPUThread& ppu, vm::ptr<CellSyncLFQueue> queu
|
||||||
|
|
||||||
if (queue->push1.compare_and_swap_test(old, push))
|
if (queue->push1.compare_and_swap_test(old, push))
|
||||||
{
|
{
|
||||||
if (!push.m_h7.data() || res)
|
if (!push.m_h7 || res)
|
||||||
{
|
{
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1143,7 +1143,7 @@ s32 _cellSyncLFQueueGetPopPointer(PPUThread& ppu, vm::ptr<CellSyncLFQueue> queue
|
||||||
|
|
||||||
s32 var2 = (s32)(s16)pop.m_h4;
|
s32 var2 = (s32)(s16)pop.m_h4;
|
||||||
s32 res;
|
s32 res;
|
||||||
if (useEventQueue && ((s32)(u16)pop.m_h1 != var2 || pop.m_h3.data() != 0))
|
if (useEventQueue && ((s32)(u16)pop.m_h1 != var2 || pop.m_h3))
|
||||||
{
|
{
|
||||||
res = CELL_SYNC_ERROR_BUSY;
|
res = CELL_SYNC_ERROR_BUSY;
|
||||||
}
|
}
|
||||||
|
@ -1190,7 +1190,7 @@ s32 _cellSyncLFQueueGetPopPointer(PPUThread& ppu, vm::ptr<CellSyncLFQueue> queue
|
||||||
|
|
||||||
if (queue->pop1.compare_and_swap_test(old, pop))
|
if (queue->pop1.compare_and_swap_test(old, pop))
|
||||||
{
|
{
|
||||||
if (!pop.m_h3.data() || res)
|
if (!pop.m_h3 || res)
|
||||||
{
|
{
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ struct sync_rwm_t // CellSyncRwm sync var
|
||||||
|
|
||||||
bool try_read_begin()
|
bool try_read_begin()
|
||||||
{
|
{
|
||||||
if (writers.data())
|
if (writers)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ struct sync_rwm_t // CellSyncRwm sync var
|
||||||
|
|
||||||
bool try_read_end()
|
bool try_read_end()
|
||||||
{
|
{
|
||||||
if (!readers.data())
|
if (!readers)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ struct sync_rwm_t // CellSyncRwm sync var
|
||||||
|
|
||||||
bool try_write_begin()
|
bool try_write_begin()
|
||||||
{
|
{
|
||||||
if (writers.data())
|
if (writers)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ s32 sys_lwmutex_lock(PPUThread& ppu, vm::ptr<sys_lwmutex_t> lwmutex, u64 timeout
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_owner.data() == tid.data())
|
if (old_owner == tid)
|
||||||
{
|
{
|
||||||
// recursive locking
|
// recursive locking
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ s32 sys_lwmutex_lock(PPUThread& ppu, vm::ptr<sys_lwmutex_t> lwmutex, u64 timeout
|
||||||
return CELL_EDEADLK;
|
return CELL_EDEADLK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lwmutex->recursive_count.data() == -1)
|
if (lwmutex->recursive_count == -1)
|
||||||
{
|
{
|
||||||
// if recursion limit reached
|
// if recursion limit reached
|
||||||
return CELL_EKRESOURCE;
|
return CELL_EKRESOURCE;
|
||||||
|
@ -180,7 +180,7 @@ s32 sys_lwmutex_trylock(PPUThread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_owner.data() == tid.data())
|
if (old_owner == tid)
|
||||||
{
|
{
|
||||||
// recursive locking
|
// recursive locking
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ s32 sys_lwmutex_trylock(PPUThread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||||
return CELL_EDEADLK;
|
return CELL_EDEADLK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lwmutex->recursive_count.data() == -1)
|
if (lwmutex->recursive_count == -1)
|
||||||
{
|
{
|
||||||
// if recursion limit reached
|
// if recursion limit reached
|
||||||
return CELL_EKRESOURCE;
|
return CELL_EKRESOURCE;
|
||||||
|
@ -244,7 +244,7 @@ s32 sys_lwmutex_unlock(PPUThread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||||
return CELL_EPERM;
|
return CELL_EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lwmutex->recursive_count.data())
|
if (lwmutex->recursive_count)
|
||||||
{
|
{
|
||||||
// recursive unlocking succeeded
|
// recursive unlocking succeeded
|
||||||
lwmutex->recursive_count--;
|
lwmutex->recursive_count--;
|
||||||
|
|
|
@ -19,14 +19,14 @@ void sys_spinlock_lock(PPUThread& ppu, vm::ptr<atomic_be_t<u32>> lock)
|
||||||
sysPrxForUser.Log("sys_spinlock_lock(lock=*0x%x)", lock);
|
sysPrxForUser.Log("sys_spinlock_lock(lock=*0x%x)", lock);
|
||||||
|
|
||||||
// prx: exchange with 0xabadcafe, repeat until exchanged with 0
|
// prx: exchange with 0xabadcafe, repeat until exchanged with 0
|
||||||
vm::wait_op(ppu, lock.addr(), 4, WRAP_EXPR(!lock->exchange(0xabadcafe).data()));
|
vm::wait_op(ppu, lock.addr(), 4, WRAP_EXPR(!lock->exchange(0xabadcafe)));
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 sys_spinlock_trylock(vm::ptr<atomic_be_t<u32>> lock)
|
s32 sys_spinlock_trylock(vm::ptr<atomic_be_t<u32>> lock)
|
||||||
{
|
{
|
||||||
sysPrxForUser.Log("sys_spinlock_trylock(lock=*0x%x)", lock);
|
sysPrxForUser.Log("sys_spinlock_trylock(lock=*0x%x)", lock);
|
||||||
|
|
||||||
if (lock->exchange(0xabadcafe).data())
|
if (lock->exchange(0xabadcafe))
|
||||||
{
|
{
|
||||||
return CELL_EBUSY;
|
return CELL_EBUSY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ s32 sys_cond_create(vm::ptr<u32> cond_id, u32 mutex_id, vm::ptr<sys_cond_attribu
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key.data() || attr->flags.data())
|
if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key || attr->flags)
|
||||||
{
|
{
|
||||||
sys_cond.Error("sys_cond_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags);
|
sys_cond.Error("sys_cond_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags);
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
|
|
|
@ -62,7 +62,7 @@ s32 sys_event_flag_create(vm::ptr<u32> id, vm::ptr<sys_event_flag_attribute_t> a
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key.data() || attr->flags.data())
|
if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key || attr->flags)
|
||||||
{
|
{
|
||||||
sys_event_flag.Error("sys_event_flag_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags);
|
sys_event_flag.Error("sys_event_flag_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags);
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
|
|
|
@ -56,7 +56,7 @@ s32 sys_mutex_create(vm::ptr<u32> mutex_id, vm::ptr<sys_mutex_attribute_t> attr)
|
||||||
|
|
||||||
const bool recursive = attr->recursive == SYS_SYNC_RECURSIVE;
|
const bool recursive = attr->recursive == SYS_SYNC_RECURSIVE;
|
||||||
|
|
||||||
if ((!recursive && attr->recursive != SYS_SYNC_NOT_RECURSIVE) || attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->adaptive != SYS_SYNC_NOT_ADAPTIVE || attr->ipc_key.data() || attr->flags.data())
|
if ((!recursive && attr->recursive != SYS_SYNC_NOT_RECURSIVE) || attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->adaptive != SYS_SYNC_NOT_ADAPTIVE || attr->ipc_key || attr->flags)
|
||||||
{
|
{
|
||||||
sys_mutex.Error("sys_mutex_create(): unknown attributes (recursive=0x%x, pshared=0x%x, adaptive=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->recursive, attr->pshared, attr->adaptive, attr->ipc_key, attr->flags);
|
sys_mutex.Error("sys_mutex_create(): unknown attributes (recursive=0x%x, pshared=0x%x, adaptive=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->recursive, attr->pshared, attr->adaptive, attr->ipc_key, attr->flags);
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ s32 sys_rwlock_create(vm::ptr<u32> rw_lock_id, vm::ptr<sys_rwlock_attribute_t> a
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key.data() || attr->flags.data())
|
if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key || attr->flags)
|
||||||
{
|
{
|
||||||
sys_rwlock.Error("sys_rwlock_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags);
|
sys_rwlock.Error("sys_rwlock_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags);
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
|
|
|
@ -35,7 +35,7 @@ s32 sys_semaphore_create(vm::ptr<u32> sem_id, vm::ptr<sys_semaphore_attribute_t>
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key.data() || attr->flags.data())
|
if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key || attr->flags)
|
||||||
{
|
{
|
||||||
sys_semaphore.Error("sys_semaphore_create(): unknown attributes (pshared=0x%x, ipc_key=0x%x, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags);
|
sys_semaphore.Error("sys_semaphore_create(): unknown attributes (pshared=0x%x, ipc_key=0x%x, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags);
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
|
|
|
@ -230,7 +230,7 @@ s32 sys_spu_thread_group_create(vm::ptr<u32> id, u32 num, s32 prio, vm::ptr<sys_
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->type.data())
|
if (attr->type)
|
||||||
{
|
{
|
||||||
sys_spu.Todo("Unsupported SPU Thread Group type (0x%x)", attr->type);
|
sys_spu.Todo("Unsupported SPU Thread Group type (0x%x)", attr->type);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue