diff --git a/Utilities/types.h b/Utilities/types.h index 8f25f04e92..a496ea1f0e 100644 --- a/Utilities/types.h +++ b/Utilities/types.h @@ -539,6 +539,12 @@ struct alignas(16) s128 CHECK_SIZE_ALIGN(u128, 16, 16); CHECK_SIZE_ALIGN(s128, 16, 16); +template <> +struct get_int_impl<16> +{ + using utype = u128; +}; + // Return magic value for any unsigned type constexpr inline struct umax_helper { diff --git a/rpcs3/Emu/Cell/Modules/cellAudio.h b/rpcs3/Emu/Cell/Modules/cellAudio.h index 2f38908abc..e2ced0f8e2 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudio.h +++ b/rpcs3/Emu/Cell/Modules/cellAudio.h @@ -38,7 +38,7 @@ enum CELL_AUDIO_BLOCK_SAMPLES = 256, CELL_AUDIO_CREATEEVENTFLAG_SPU = 0x00000001, - + CELL_AUDIO_EVENT_MIX = 0, CELL_AUDIO_EVENT_HEADPHONE = 1, @@ -144,7 +144,7 @@ struct audio_port u32 size; u64 timestamp; // copy of global timestamp - struct alignas(8) level_set_t + struct level_set_t { float value; float inc; diff --git a/rpcs3/Emu/Cell/Modules/cellPamf.h b/rpcs3/Emu/Cell/Modules/cellPamf.h index b3cd294950..acb87f115c 100644 --- a/rpcs3/Emu/Cell/Modules/cellPamf.h +++ b/rpcs3/Emu/Cell/Modules/cellPamf.h @@ -410,7 +410,7 @@ bool squeue_test_exit(); template class squeue_t { - struct alignas(8) squeue_sync_var_t + struct squeue_sync_var_t { struct { diff --git a/rpcs3/Emu/Cell/Modules/cellSpurs.h b/rpcs3/Emu/Cell/Modules/cellSpurs.h index dc991b3ec7..ecc3d1d219 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpurs.h +++ b/rpcs3/Emu/Cell/Modules/cellSpurs.h @@ -692,7 +692,7 @@ struct alignas(128) CellSpurs u8 xCA; // 0xCA u8 xCB; // 0xCB - struct alignas(4) SrvTraceSyncVar + struct SrvTraceSyncVar { u8 sysSrvTraceInitialised; // 0xCC u8 sysSrvNotifyUpdateTraceComplete; // 0xCD @@ -881,7 +881,7 @@ CHECK_SIZE_ALIGN(CellSpursWorkloadAttribute, 512, 8); struct alignas(128) CellSpursEventFlag { - struct alignas(8) ControlSyncVar + struct ControlSyncVar { be_t events; // 0x00 Event bits be_t spuTaskPendingRecv; // 0x02 A bit is set to 1 when the condition of the SPU task using the slot are met and back to 0 when the SPU task unblocks diff --git a/rpcs3/Emu/Cell/Modules/cellSync.h b/rpcs3/Emu/Cell/Modules/cellSync.h index a003b1a570..ea53398a5f 100644 --- a/rpcs3/Emu/Cell/Modules/cellSync.h +++ b/rpcs3/Emu/Cell/Modules/cellSync.h @@ -36,7 +36,7 @@ enum CellSyncError1 : u32 struct CellSyncMutex { - struct alignas(4) Counter + struct Counter { be_t rel; be_t acq; @@ -162,7 +162,7 @@ CHECK_SIZE_ALIGN(CellSyncRwm, 16, 16); struct alignas(32) CellSyncQueue { - struct alignas(8) ctrl_t + struct ctrl_t { union { @@ -290,7 +290,7 @@ enum CellSyncQueueDirection : u32 // CellSyncLFQueueDirection struct alignas(128) CellSyncLFQueue { - struct alignas(8) pop1_t + struct pop1_t { be_t m_h1; be_t m_h2; @@ -303,13 +303,13 @@ struct alignas(128) CellSyncLFQueue be_t pack; }; - struct alignas(4) pop3_t + struct pop3_t { be_t m_h1; be_t m_h2; }; - struct alignas(8) push1_t + struct push1_t { be_t m_h5; be_t m_h6; @@ -322,7 +322,7 @@ struct alignas(128) CellSyncLFQueue be_t pack; }; - struct alignas(4) push3_t + struct push3_t { be_t m_h5; be_t m_h6; diff --git a/rpcs3/util/atomic.hpp b/rpcs3/util/atomic.hpp index a13e0d502f..4b5b5b83a4 100644 --- a/rpcs3/util/atomic.hpp +++ b/rpcs3/util/atomic.hpp @@ -254,10 +254,10 @@ void atomic_wait::list::wait(atomic_wait_timeout timeout) template struct atomic_storage { - static_assert(sizeof(T) <= 16 && sizeof(T) == alignof(T), "atomic_storage<> error: invalid type"); - /* First part: Non-MSVC intrinsics */ + using type = get_uint_t; + #ifndef _MSC_VER #if defined(__ATOMIC_HLE_ACQUIRE) && defined(__ATOMIC_HLE_RELEASE) @@ -270,19 +270,19 @@ struct atomic_storage static inline bool compare_exchange(T& dest, T& comp, T exch) { - return __atomic_compare_exchange(&dest, &comp, &exch, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return __atomic_compare_exchange(reinterpret_cast(&dest), reinterpret_cast(&comp), reinterpret_cast(&exch), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } static inline bool compare_exchange_hle_acq(T& dest, T& comp, T exch) { static_assert(sizeof(T) == 4 || sizeof(T) == 8); - return __atomic_compare_exchange(&dest, &comp, &exch, false, s_hle_ack, s_hle_ack); + return __atomic_compare_exchange(reinterpret_cast(&dest), reinterpret_cast(&comp), reinterpret_cast(&exch), false, s_hle_ack, s_hle_ack); } static inline T load(const T& dest) { T result; - __atomic_load(&dest, &result, __ATOMIC_SEQ_CST); + __atomic_load(reinterpret_cast(&dest), reinterpret_cast(&result), __ATOMIC_SEQ_CST); return result; } @@ -293,13 +293,13 @@ struct atomic_storage static inline void release(T& dest, T value) { - __atomic_store(&dest, &value, __ATOMIC_RELEASE); + __atomic_store(reinterpret_cast(&dest), reinterpret_cast(&value), __ATOMIC_RELEASE); } static inline T exchange(T& dest, T value) { T result; - __atomic_exchange(&dest, &value, &result, __ATOMIC_SEQ_CST); + __atomic_exchange(reinterpret_cast(&dest), reinterpret_cast(&value), reinterpret_cast(&result), __ATOMIC_SEQ_CST); return result; } @@ -909,6 +909,7 @@ struct atomic_storage : atomic_storage static inline T exchange(T& dest, T value) { + __atomic_thread_fence(__ATOMIC_ACQ_REL); return std::bit_cast(__sync_lock_test_and_set(reinterpret_cast(&dest), std::bit_cast(value))); } @@ -929,7 +930,7 @@ struct atomic_storage : atomic_storage }; // Atomic type with lock-free and standard layout guarantees (and appropriate limitations) -template +template class atomic_t { protected: @@ -937,11 +938,22 @@ protected: using ptr_rt = std::conditional_t, ullong, type>; - static_assert(alignof(type) == sizeof(type), "atomic_t<> error: unexpected alignment, use alignas() if necessary"); + static_assert((Align & (Align - 1)) == 0, "atomic_t<> error: unexpected Align parameter (not power of 2)."); + static_assert(Align % sizeof(type) == 0, "atomic_t<> error: invalid type, must be power of 2."); + static_assert(sizeof(type) <= 16, "atomic_t<> error: invalid type, too big (max supported size is 16)."); + static_assert(Align >= sizeof(type), "atomic_t<> error: bad args, specify bigger alignment if necessary."); + + static_assert(std::is_trivially_copyable_v); + static_assert(std::is_copy_constructible_v); + static_assert(std::is_move_constructible_v); + static_assert(std::is_copy_assignable_v); + static_assert(std::is_move_assignable_v); alignas(Align) type m_data; public: + static constexpr std::size_t align = Align; + atomic_t() noexcept = default; atomic_t(const atomic_t&) = delete;