16#ifdef UACPI_OVERRIDE_ATOMIC
17#include "uacpi_atomic.h"
22#if defined(_MSC_VER) && !defined(__clang__)
27#define UACPI_MAKE_MSVC_CMPXCHG(width, type, suffix) \
28 static inline int uacpi_do_atomic_cmpxchg##width( \
29 type volatile *ptr, type volatile *expected, type desired \
34 current = _InterlockedCompareExchange##suffix(ptr, *expected, desired); \
35 if (current != *expected) { \
36 *expected = current; \
42#define UACPI_MSVC_CMPXCHG_INVOKE(ptr, expected, desired, width, type) \
43 uacpi_do_atomic_cmpxchg##width( \
44 (type volatile*)ptr, (type volatile*)expected, desired \
47#define UACPI_MSVC_ATOMIC_STORE(ptr, value, type, width) \
48 _InterlockedExchange##width((type volatile*)(ptr), (type)(value))
50#define UACPI_MSVC_ATOMIC_LOAD(ptr, type, width) \
51 _InterlockedOr##width((type volatile*)(ptr), 0)
53#define UACPI_MSVC_ATOMIC_INC(ptr, type, width) \
54 _InterlockedIncrement##width((type volatile*)(ptr))
56#define UACPI_MSVC_ATOMIC_DEC(ptr, type, width) \
57 _InterlockedDecrement##width((type volatile*)(ptr))
59UACPI_MAKE_MSVC_CMPXCHG(64,
__int64, 64)
60UACPI_MAKE_MSVC_CMPXCHG(32,
long,)
61UACPI_MAKE_MSVC_CMPXCHG(16,
short, 16)
63#define uacpi_atomic_cmpxchg16(ptr, expected, desired) \
64 UACPI_MSVC_CMPXCHG_INVOKE(ptr, expected, desired, 16, short)
66#define uacpi_atomic_cmpxchg32(ptr, expected, desired) \
67 UACPI_MSVC_CMPXCHG_INVOKE(ptr, expected, desired, 32, long)
69#define uacpi_atomic_cmpxchg64(ptr, expected, desired) \
70 UACPI_MSVC_CMPXCHG_INVOKE(ptr, expected, desired, 64, __int64)
72#define uacpi_atomic_load8(ptr) UACPI_MSVC_ATOMIC_LOAD(ptr, char, 8)
73#define uacpi_atomic_load16(ptr) UACPI_MSVC_ATOMIC_LOAD(ptr, short, 16)
74#define uacpi_atomic_load32(ptr) UACPI_MSVC_ATOMIC_LOAD(ptr, long,)
75#define uacpi_atomic_load64(ptr) UACPI_MSVC_ATOMIC_LOAD(ptr, __int64, 64)
77#define uacpi_atomic_store8(ptr, value) UACPI_MSVC_ATOMIC_STORE(ptr, value, char, 8)
78#define uacpi_atomic_store16(ptr, value) UACPI_MSVC_ATOMIC_STORE(ptr, value, short, 16)
79#define uacpi_atomic_store32(ptr, value) UACPI_MSVC_ATOMIC_STORE(ptr, value, long,)
80#define uacpi_atomic_store64(ptr, value) UACPI_MSVC_ATOMIC_STORE(ptr, value, __int64, 64)
82#define uacpi_atomic_inc16(ptr) UACPI_MSVC_ATOMIC_INC(ptr, short, 16)
83#define uacpi_atomic_inc32(ptr) UACPI_MSVC_ATOMIC_INC(ptr, long,)
84#define uacpi_atomic_inc64(ptr) UACPI_MSVC_ATOMIC_INC(ptr, __int64, 64)
86#define uacpi_atomic_dec16(ptr) UACPI_MSVC_ATOMIC_DEC(ptr, short, 16)
87#define uacpi_atomic_dec32(ptr) UACPI_MSVC_ATOMIC_DEC(ptr, long,)
88#define uacpi_atomic_dec64(ptr) UACPI_MSVC_ATOMIC_DEC(ptr, __int64, 64)
89#elif defined(__WATCOMC__)
94#pragma aux uacpi_do_atomic_cmpxchg16 = \
97 "lock cmpxchg [edi], bx" \
101 parm [ edi ] [ esi ] [ ebx ] \
105#pragma aux uacpi_do_atomic_cmpxchg32 = \
108 "lock cmpxchg [edi], ebx" \
112 parm [ edi ] [ esi ] [ ebx ] \
116#pragma aux uacpi_do_atomic_cmpxchg64_asm = \
119 "mov edx, [esi + 4]" \
120 "lock cmpxchg8b [edi]" \
122 "mov [esi + 4], edx" \
126 parm [ edi ] [ esi ] [ ebx ] [ ecx ] \
133#define uacpi_atomic_cmpxchg16(ptr, expected, desired) \
134 uacpi_do_atomic_cmpxchg16((volatile uint16_t*)ptr, (volatile uint16_t*)expected, (uint16_t)desired)
135#define uacpi_atomic_cmpxchg32(ptr, expected, desired) \
136 uacpi_do_atomic_cmpxchg32((volatile uint32_t*)ptr, (volatile uint32_t*)expected, (uint32_t)desired)
137#define uacpi_atomic_cmpxchg64(ptr, expected, desired) \
138 uacpi_do_atomic_cmpxchg64((volatile uint64_t*)ptr, (volatile uint64_t*)expected, (uint64_t)desired)
141#pragma aux uacpi_do_atomic_load8 = \
147#pragma aux uacpi_do_atomic_load16 = \
153#pragma aux uacpi_do_atomic_load32 = \
159#pragma aux uacpi_do_atomic_load64_asm = \
165 "lock cmpxchg8b [esi]" \
167 "mov [edi + 4], edx" \
168 modify [ eax ebx ecx edx ] \
173 uacpi_do_atomic_load64_asm(
ptr, &
value);
177#define uacpi_atomic_load8(ptr) uacpi_do_atomic_load8((volatile uint8_t*)ptr)
178#define uacpi_atomic_load16(ptr) uacpi_do_atomic_load16((volatile uint16_t*)ptr)
179#define uacpi_atomic_load32(ptr) uacpi_do_atomic_load32((volatile uint32_t*)ptr)
180#define uacpi_atomic_load64(ptr) uacpi_do_atomic_load64((volatile uint64_t*)ptr)
183#pragma aux uacpi_do_atomic_store8 = \
188#pragma aux uacpi_do_atomic_store16 = \
193#pragma aux uacpi_do_atomic_store32 = \
198#pragma aux uacpi_do_atomic_store64_asm = \
202 "retry: lock cmpxchg8b [edi]" \
205 parm [ edi ] [ ebx ] [ ecx ]
211#define uacpi_atomic_store8(ptr, value) uacpi_do_atomic_store8((volatile uint8_t*)ptr, (uint8_t)value)
212#define uacpi_atomic_store16(ptr, value) uacpi_do_atomic_store16((volatile uint16_t*)ptr, (uint16_t)value)
213#define uacpi_atomic_store32(ptr, value) uacpi_do_atomic_store32((volatile uint32_t*)ptr, (uint32_t)value)
214#define uacpi_atomic_store64(ptr, value) uacpi_do_atomic_store64((volatile uint64_t*)ptr, (uint64_t)value)
217#pragma aux uacpi_do_atomic_inc16 = \
220 "lock xadd [edi], ax" \
226#pragma aux uacpi_do_atomic_inc32 = \
229 "lock xadd [edi], eax" \
235#pragma aux uacpi_do_atomic_inc64_asm = \
241 "retry: lock cmpxchg8b [esi]" \
248 "mov [edi + 4], ecx" \
249 modify [ eax ebx ecx edx ] \
254 uacpi_do_atomic_inc64_asm(
ptr, &
value);
258#define uacpi_atomic_inc16(ptr) uacpi_do_atomic_inc16((volatile uint16_t*)ptr)
259#define uacpi_atomic_inc32(ptr) uacpi_do_atomic_inc32((volatile uint32_t*)ptr)
260#define uacpi_atomic_inc64(ptr) uacpi_do_atomic_inc64((volatile uint64_t*)ptr)
263#pragma aux uacpi_do_atomic_dec16 = \
266 "lock xadd [edi], ax" \
272#pragma aux uacpi_do_atomic_dec32 = \
275 "lock xadd [edi], eax" \
281#pragma aux uacpi_do_atomic_dec64_asm = \
287 "retry: lock cmpxchg8b [esi]" \
294 "mov [edi + 4], ecx" \
295 modify [ eax ebx ecx edx ] \
300 uacpi_do_atomic_dec64_asm(
ptr, &
value);
304#define uacpi_atomic_dec16(ptr) uacpi_do_atomic_dec16((volatile uint16_t*)ptr)
305#define uacpi_atomic_dec32(ptr) uacpi_do_atomic_dec32((volatile uint32_t*)ptr)
306#define uacpi_atomic_dec64(ptr) uacpi_do_atomic_dec64((volatile uint64_t*)ptr)
309#define UACPI_DO_CMPXCHG(ptr, expected, desired) \
310 __atomic_compare_exchange_n(ptr, expected, desired, 0, \
311 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)
313#define uacpi_atomic_cmpxchg16(ptr, expected, desired) \
314 UACPI_DO_CMPXCHG(ptr, expected, desired)
315#define uacpi_atomic_cmpxchg32(ptr, expected, desired) \
316 UACPI_DO_CMPXCHG(ptr, expected, desired)
317#define uacpi_atomic_cmpxchg64(ptr, expected, desired) \
318 UACPI_DO_CMPXCHG(ptr, expected, desired)
320#define uacpi_atomic_load8(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE)
321#define uacpi_atomic_load16(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE)
322#define uacpi_atomic_load32(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE)
323#define uacpi_atomic_load64(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE)
325#define uacpi_atomic_store8(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_RELEASE)
326#define uacpi_atomic_store16(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_RELEASE)
327#define uacpi_atomic_store32(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_RELEASE)
328#define uacpi_atomic_store64(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_RELEASE)
330#define uacpi_atomic_inc16(ptr) __atomic_add_fetch(ptr, 1, __ATOMIC_ACQ_REL)
331#define uacpi_atomic_inc32(ptr) __atomic_add_fetch(ptr, 1, __ATOMIC_ACQ_REL)
332#define uacpi_atomic_inc64(ptr) __atomic_add_fetch(ptr, 1, __ATOMIC_ACQ_REL)
334#define uacpi_atomic_dec16(ptr) __atomic_sub_fetch(ptr, 1, __ATOMIC_ACQ_REL)
335#define uacpi_atomic_dec32(ptr) __atomic_sub_fetch(ptr, 1, __ATOMIC_ACQ_REL)
336#define uacpi_atomic_dec64(ptr) __atomic_sub_fetch(ptr, 1, __ATOMIC_ACQ_REL)
339#if UACPI_POINTER_SIZE == 4
340#define uacpi_atomic_load_ptr(ptr_to_ptr) uacpi_atomic_load32(ptr_to_ptr)
341#define uacpi_atomic_store_ptr(ptr_to_ptr, value) uacpi_atomic_store32(ptr_to_ptr, value)
343#define uacpi_atomic_load_ptr(ptr_to_ptr) uacpi_atomic_load64(ptr_to_ptr)
344#define uacpi_atomic_store_ptr(ptr_to_ptr, value) uacpi_atomic_store64(ptr_to_ptr, value)
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out