diff --git a/miniaudio.h b/miniaudio.h index b514d09c..b435651b 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -13811,11 +13811,17 @@ typedef unsigned char c89atomic_bool; #define C89ATOMIC_32BIT #endif #endif +#if defined(__arm__) || defined(_M_ARM) +#define C89ATOMIC_ARM32 +#endif +#if defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) +#define C89ATOMIC_ARM64 +#endif #if defined(__x86_64__) || defined(_M_X64) #define C89ATOMIC_X64 #elif defined(__i386) || defined(_M_IX86) #define C89ATOMIC_X86 -#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) +#elif defined(C89ATOMIC_ARM32) || defined(C89ATOMIC_ARM64) #define C89ATOMIC_ARM #endif #if defined(_MSC_VER) @@ -13836,6 +13842,56 @@ typedef unsigned char c89atomic_bool; #define C89ATOMIC_HAS_32 #define C89ATOMIC_HAS_64 #if (defined(_MSC_VER) ) || defined(__WATCOMC__) || defined(__DMC__) + #define C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, intrin, c89atomicType, msvcType) \ + c89atomicType result; \ + switch (order) \ + { \ + case c89atomic_memory_order_relaxed: \ + { \ + result = (c89atomicType)intrin##_nf((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + case c89atomic_memory_order_consume: \ + case c89atomic_memory_order_acquire: \ + { \ + result = (c89atomicType)intrin##_acq((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + case c89atomic_memory_order_release: \ + { \ + result = (c89atomicType)intrin##_rel((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + case c89atomic_memory_order_acq_rel: \ + case c89atomic_memory_order_seq_cst: \ + default: \ + { \ + result = (c89atomicType)intrin((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + } \ + return result; + #define C89ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, expected, desired, order, intrin, c89atomicType, msvcType) \ + c89atomicType result; \ + switch (order) \ + { \ + case c89atomic_memory_order_relaxed: \ + { \ + result = (c89atomicType)intrin##_nf((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \ + } break; \ + case c89atomic_memory_order_consume: \ + case c89atomic_memory_order_acquire: \ + { \ + result = (c89atomicType)intrin##_acq((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \ + } break; \ + case c89atomic_memory_order_release: \ + { \ + result = (c89atomicType)intrin##_rel((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \ + } break; \ + case c89atomic_memory_order_acq_rel: \ + case c89atomic_memory_order_seq_cst: \ + default: \ + { \ + result = (c89atomicType)intrin((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \ + } break; \ + } \ + return result; #define c89atomic_memory_order_relaxed 0 #define c89atomic_memory_order_consume 1 #define c89atomic_memory_order_acquire 2 @@ -13974,29 +14030,45 @@ typedef unsigned char c89atomic_bool; #if defined(C89ATOMIC_HAS_8) static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_exchange_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange8, c89atomic_uint8, char); + #else (void)order; return (c89atomic_uint8)_InterlockedExchange8((volatile char*)dst, (char)src); + #endif } #endif #if defined(C89ATOMIC_HAS_16) static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_exchange_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange16, c89atomic_uint16, short); + #else (void)order; return (c89atomic_uint16)_InterlockedExchange16((volatile short*)dst, (short)src); + #endif } #endif #if defined(C89ATOMIC_HAS_32) static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_exchange_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange, c89atomic_uint32, long); + #else (void)order; return (c89atomic_uint32)_InterlockedExchange((volatile long*)dst, (long)src); + #endif } #endif #if defined(C89ATOMIC_HAS_64) && defined(C89ATOMIC_64BIT) static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_exchange_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange64, c89atomic_uint64, long long); + #else (void)order; return (c89atomic_uint64)_InterlockedExchange64((volatile long long*)dst, (long long)src); + #endif } #else #endif @@ -14059,29 +14131,45 @@ typedef unsigned char c89atomic_bool; #if defined(C89ATOMIC_HAS_8) static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_fetch_add_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd8, c89atomic_uint8, char); + #else (void)order; return (c89atomic_uint8)_InterlockedExchangeAdd8((volatile char*)dst, (char)src); + #endif } #endif #if defined(C89ATOMIC_HAS_16) static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_fetch_add_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd16, c89atomic_uint16, short); + #else (void)order; return (c89atomic_uint16)_InterlockedExchangeAdd16((volatile short*)dst, (short)src); + #endif } #endif #if defined(C89ATOMIC_HAS_32) static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_fetch_add_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd, c89atomic_uint32, long); + #else (void)order; return (c89atomic_uint32)_InterlockedExchangeAdd((volatile long*)dst, (long)src); + #endif } #endif #if defined(C89ATOMIC_HAS_64) && defined(C89ATOMIC_64BIT) static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_add_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd64, c89atomic_uint64, long long); + #else (void)order; return (c89atomic_uint64)_InterlockedExchangeAdd64((volatile long long*)dst, (long long)src); + #endif } #else #endif @@ -14110,6 +14198,8 @@ typedef unsigned char c89atomic_bool; #else #if defined(C89ATOMIC_X64) #define c89atomic_thread_fence(order) __faststorefence(), (void)order + #elif defined(C89ATOMIC_ARM64) + #define c89atomic_thread_fence(order) __dmb(_ARM64_BARRIER_ISH), (void)order #else static C89ATOMIC_INLINE void c89atomic_thread_fence(c89atomic_memory_order order) { @@ -14123,29 +14213,45 @@ typedef unsigned char c89atomic_bool; #if defined(C89ATOMIC_HAS_8) static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_load_explicit_8(volatile const c89atomic_uint8* ptr, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange8, c89atomic_uint8, char); + #else (void)order; return c89atomic_compare_and_swap_8((volatile c89atomic_uint8*)ptr, 0, 0); + #endif } #endif #if defined(C89ATOMIC_HAS_16) static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_load_explicit_16(volatile const c89atomic_uint16* ptr, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange16, c89atomic_uint16, short); + #else (void)order; return c89atomic_compare_and_swap_16((volatile c89atomic_uint16*)ptr, 0, 0); + #endif } #endif #if defined(C89ATOMIC_HAS_32) static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_load_explicit_32(volatile const c89atomic_uint32* ptr, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange, c89atomic_uint32, long); + #else (void)order; return c89atomic_compare_and_swap_32((volatile c89atomic_uint32*)ptr, 0, 0); + #endif } #endif #if defined(C89ATOMIC_HAS_64) static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_load_explicit_64(volatile const c89atomic_uint64* ptr, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange64, c89atomic_uint64, long long); + #else (void)order; return c89atomic_compare_and_swap_64((volatile c89atomic_uint64*)ptr, 0, 0); + #endif } #endif #if defined(C89ATOMIC_HAS_8) @@ -14215,6 +14321,9 @@ typedef unsigned char c89atomic_bool; #if defined(C89ATOMIC_HAS_8) static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_fetch_and_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd8, c89atomic_uint8, char); + #else c89atomic_uint8 oldValue; c89atomic_uint8 newValue; do { @@ -14223,11 +14332,15 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_16) static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_fetch_and_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd16, c89atomic_uint16, short); + #else c89atomic_uint16 oldValue; c89atomic_uint16 newValue; do { @@ -14236,11 +14349,15 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_32) static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_fetch_and_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd, c89atomic_uint32, long); + #else c89atomic_uint32 oldValue; c89atomic_uint32 newValue; do { @@ -14249,11 +14366,15 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_32(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_64) static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_and_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd64, c89atomic_uint64, long long); + #else c89atomic_uint64 oldValue; c89atomic_uint64 newValue; do { @@ -14262,11 +14383,15 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_8) static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_fetch_xor_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor8, c89atomic_uint8, char); + #else c89atomic_uint8 oldValue; c89atomic_uint8 newValue; do { @@ -14275,11 +14400,15 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_16) static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_fetch_xor_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor16, c89atomic_uint16, short); + #else c89atomic_uint16 oldValue; c89atomic_uint16 newValue; do { @@ -14288,11 +14417,15 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_32) static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_fetch_xor_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor, c89atomic_uint32, long); + #else c89atomic_uint32 oldValue; c89atomic_uint32 newValue; do { @@ -14301,11 +14434,15 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_32(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_64) static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_xor_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor64, c89atomic_uint64, long long); + #else c89atomic_uint64 oldValue; c89atomic_uint64 newValue; do { @@ -14314,11 +14451,15 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_8) static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_fetch_or_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr8, c89atomic_uint8, char); + #else c89atomic_uint8 oldValue; c89atomic_uint8 newValue; do { @@ -14327,11 +14468,15 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_16) static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_fetch_or_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr16, c89atomic_uint16, short); + #else c89atomic_uint16 oldValue; c89atomic_uint16 newValue; do { @@ -14340,11 +14485,15 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_32) static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_fetch_or_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr, c89atomic_uint32, long); + #else c89atomic_uint32 oldValue; c89atomic_uint32 newValue; do { @@ -14353,11 +14502,15 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_32(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_64) static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_or_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order) { + #if defined(C89ATOMIC_ARM) + C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr64, c89atomic_uint64, long long); + #else c89atomic_uint64 oldValue; c89atomic_uint64 newValue; do { @@ -14366,6 +14519,7 @@ typedef unsigned char c89atomic_bool; } while (c89atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue); (void)order; return oldValue; + #endif } #endif #if defined(C89ATOMIC_HAS_8)